最大流与最小割

1、POJ 3713 Transferring Sylla

题意:判断一个无向图是否三连通?

思路:枚举每个点,删去后用Tarjan判断图中是否存在割点,如果存在则该图不满足三连通性。

// #include<bits/stdc++.h>
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring> // for memset
#include <vector> // vector<int>().swap(v);

#define IOS ios_base::sync_with_stdio(0); cin.tie(0)
#define lowbit(x) (x&(-x))
using namespace std;
typedef long long ll;

int del,root;
bool cut;
int dfn[510], low[510];

vector<int> e[510];
int n,m;
int tot;

void Tarjan(int u,int p)
{
    if(cut) return;
    dfn[u]=low[u]= ++tot;
    int son=0;
    for(vector<int>::iterator it=e[u].begin();it!=e[u].end();it++)
    {
        int v=*it;
        if(v==p || v==del)    continue;
        if(!dfn[v])
        {
            son++;
            Tarjan(v,u);
            low[u]=min(low[u],low[v]);
            if((u == root && son > 1) || (u != root && low[v] >= dfn[u]))
            {
                cut=true;
                return;
            }
        }else{
            low[u]=min(low[u],dfn[v]);
        }
    }
}

int main(void)
{
    while (scanf("%d%d", &n, &m) != EOF && n) {
        for (int i = 0; i < n; ++i) e[i].clear();
        for (int i = 0; i < m; ++i) {
            int u, v;
            scanf("%d%d", &u, &v);
            e[u].push_back(v);
            e[v].push_back(u);
        }
        cut = 0;
        for (int i = 0; i < n; ++i) {
            del = i;
            memset(dfn, 0, sizeof(dfn));
            tot = 0;
            root = !i;

            Tarjan(root, -1);
            if (cut) break;
            for (int j = 0; j < n; ++j) {
                if (j != del && !dfn[j]) {
                    cut = 1;
                    break;
                }
            }
            if (cut) break;
        }
        printf("%s\n", cut ? "NO" : "YES");
    }

    return 0;
}

 

2、POJ 2987 Firing

题意:老板决定大裁员,每开除一个人,同时要将其下属一并开除,以及下属的下属... ... 给出开除掉每个人的贡献值和各种从属关系,求最小裁员数及最大贡献值和。

定义一个有向图 G=(V,E) 的闭合图是该有向图的一个点集,且该点集的所有出边都还指向该点集。即闭合图内的任意点的任意后继也一定在闭合图中。
// 最大权闭合图的求解方法是:

1.先构造网络流N,添加源点s,从s到正权值点做一条边,容量为点的权值。

2.添加汇点t,从负权值点到t做一条边,容量为点的权值的绝对值。

3.原来的边的容量统统设为无穷大。

4.求解最小割,最大权=正权值之和-最小割权值

5.残余网络中的点的个数即为裁员个数。

感觉网络流不是很好理解,这个题先放一下

 

 

3、POJ 2914 Minimum Cut

题意:求无向图的最小割。

思路:Stoer-Wagner算法

 哎这道题还是一头雾水,还是先放一下,滚去复习图论的知识点了 555 菜到无法呼吸

 

posted @ 2020-06-08 21:33  ジャスミン  阅读(202)  评论(0编辑  收藏  举报