Stoer-Wagner算法訓練題目合集 hdu 3691 hdu3002 poj 2914

題意:都是求全局最小割


思路:訓練時發現網絡流是我們隊伍一大缺陷,就看了一天多的網絡流,然後也學會了Stoer-Wagner算法

要注意的是輸入會有重邊,所以不能只賦值一次,這個做任何圖論題都要注意


hdu 3691:http://acm.hdu.edu.cn/showproblem.php?pid=3691


#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

const int maxn = 105;
const int inf = 0x3f3f3f3f;

struct Stoer_Wagner
{
    int n, g[maxn][maxn], b[maxn], dist[maxn];

    void init(int n, int w[maxn][maxn])
    {
        this->n = n;
        for(int i = 1; i <= n; i++)
        {
            for(int j = 1; j <= n; j++)
            {
                g[i][j] = w[i][j];
            }
        }
    }

    int Min_Cut_Phase(int ph, int &x, int &y)
    {
        int t = 1;
        int i, j;
        b[t] = ph;
        for(i = 1; i <= n; i++)
            if(b[i] != ph)
                dist[i] = g[1][i];
        for(i = 1; i < n; i++)
        {
            x = t;
            for(t = 0, j = 1; j <= n; j++)
                if(b[j] != ph && (!t || dist[j] > dist[t]))
                    t = j;
            b[t] = ph;
            for(j = 1; j <= n; j++)
                if(b[j] != ph)
                    dist[j] += g[t][j];
        }
        return y = t, dist[t];
    }

    void Merge(int x, int y)
    {
        if(x > y)
            swap(x, y);
        for(int i = 1; i <= n; i++)
        {
            if(i != x && i != y)
                g[i][x] += g[i][y], g[x][i] += g[i][y];
        }
        if(y == n)
            return ;
        for(int i = 1; i < n; i++)
        {
            if(i != y)
            {
                swap(g[i][y], g[i][n]);
                swap(g[y][i], g[n][i]);
            }
        }
    }

    int Min_Cut()
    {
        int ret = inf, x, y;
        memset(b, 0, sizeof(b));
        for(int i = 1; n > 1; i++, n--)
        {
            ret = min(ret, Min_Cut_Phase(i, x, y));
            Merge(x, y);
        }
        return ret;
    }
};

Stoer_Wagner sw;
int w[maxn][maxn];

int main()
{
    int n, m;
    while(~scanf("%d%d", &n, &m))
    {
        int u, v, c;
        memset(w, 0, sizeof(w));
        for(int i = 1; i <= m; i++)
        {
            scanf("%d%d%d", &u, &v, &c);
            u++, v++;
            w[u][v] += c;
            w[v][u] += c;
        }
        sw.init(n, w);
        int ans = sw.Min_Cut();
        printf("%d\n", ans);
    }
    return 0;
}

hdu 3002: http://acm.hdu.edu.cn/showproblem.php?pid=3002


#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

const int maxn = 105;
const int inf = 0x3f3f3f3f;

struct Stoer_Wagner
{
    int n, g[maxn][maxn], b[maxn], dist[maxn];

    void init(int n, int w[maxn][maxn])
    {
        this->n = n;
        for(int i = 1; i <= n; i++)
        {
            for(int j = 1; j <= n; j++)
            {
                g[i][j] = w[i][j];
            }
        }
    }

    int Min_Cut_Phase(int ph, int &x, int &y)
    {
        int t = 1;
        int i, j;
        b[t] = ph;
        for(i = 1; i <= n; i++)
            if(b[i] != ph)
                dist[i] = g[1][i];
        for(i = 1; i < n; i++)
        {
            x = t;
            for(t = 0, j = 1; j <= n; j++)
                if(b[j] != ph && (!t || dist[j] > dist[t]))
                    t = j;
            b[t] = ph;
            for(j = 1; j <= n; j++)
                if(b[j] != ph)
                    dist[j] += g[t][j];
        }
        return y = t, dist[t];
    }

    void Merge(int x, int y)
    {
        if(x > y)
            swap(x, y);
        for(int i = 1; i <= n; i++)
        {
            if(i != x && i != y)
                g[i][x] += g[i][y], g[x][i] += g[i][y];
        }
        if(y == n)
            return ;
        for(int i = 1; i < n; i++)
        {
            if(i != y)
            {
                swap(g[i][y], g[i][n]);
                swap(g[y][i], g[n][i]);
            }
        }
    }

    int Min_Cut()
    {
        int ret = inf, x, y;
        memset(b, 0, sizeof(b));
        for(int i = 1; n > 1; i++, n--)
        {
            ret = min(ret, Min_Cut_Phase(i, x, y));
            Merge(x, y);
        }
        return ret;
    }
};

Stoer_Wagner sw;
int w[maxn][maxn];

int main()
{
    int n, m;
    while(~scanf("%d%d", &n, &m))
    {
        int u, v, c;
        memset(w, 0, sizeof(w));
        for(int i = 1; i <= m; i++)
        {
            scanf("%d%d%d", &u, &v, &c);
            u++, v++;
            w[u][v] += c;
            w[v][u] += c;
        }
        sw.init(n, w);
        int ans = sw.Min_Cut();
        printf("%d\n", ans);
    }
    return 0;
}




poj 2914:http://poj.org/problem?id=2914


#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

const int maxn = 505;
const int inf = 0x3f3f3f3f;

struct Stoer_Wagner
{
	int n, g[maxn][maxn], b[maxn], dist[maxn];

	void init(int n, int w[maxn][maxn])
	{
		this->n = n;
		for(int i = 1; i <= n; i++)
		{
			for(int j = 1; j <= n; j++)
			{
				g[i][j] = w[i][j];
			}
		}
	}

	int Min_Cut_Phase(int ph, int &x, int &y)
	{
		int t = 1;
		int i, j;
		b[t] = ph;
		for(i = 1; i <= n; i++)
            if(b[i] != ph)
                dist[i] = g[1][i];
		for(i = 1; i < n; i++)
		{
			x = t;
			for(t = 0, j = 1; j <= n; j++)
				if(b[j] != ph && (!t || dist[j] > dist[t]))
					t = j;
			b[t] = ph;
			for(j = 1; j <= n; j++)
				if(b[j] != ph)
					dist[j] += g[t][j];
		}
		return y = t, dist[t];
	}

	void Merge(int x, int y)
	{
		if(x > y)
			swap(x, y);
		for(int i = 1; i <= n; i++)
		{
			if(i != x && i != y)
				g[i][x] += g[i][y], g[x][i] += g[i][y];
		}
		if(y == n)
			return ;
		for(int i = 1; i < n; i++)
		{
			if(i != y)
			{
				swap(g[i][y], g[i][n]);
				swap(g[y][i], g[n][i]);
			}
		}
	}

	int Min_Cut()
	{
		int ret = inf, x, y;
		memset(b, 0, sizeof(b));
		for(int i = 1; n > 1; i++, n--)
		{
			ret = min(ret, Min_Cut_Phase(i, x, y));
			Merge(x, y);
		}
		return ret;
	}
};

Stoer_Wagner sw;
int w[maxn][maxn];

int main()
{
	int n, m;
	while(~scanf("%d%d", &n, &m))
	{
		int u, v, c;
		memset(w, 0, sizeof(w));
		for(int i = 1; i <= m; i++)
		{
			scanf("%d%d%d", &u, &v, &c);
			u++, v++;
			w[u][v] += c;
			w[v][u] += c;
		}
		sw.init(n, w);
		int ans = sw.Min_Cut();
		printf("%d\n", ans);
	}
	return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章