无向图求最少删除多少点使得剩下的图不连通 网络流最小割+拆点

//#define LOCAL
#include <bits/stdc++.h>

using namespace std;
#define ll long long
#define mem(a, b) memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define DNF 0x7f
#define DBG printf("this is a input\n")
#define fi first
#define se second
#define mk(a, b) make_pair(a,b)
#define pb push_back
#define p_queue priority_queue
#define eps 1e-8
ll gcd(ll a, ll b) {
    return b == 0 ? a : gcd(b, a % b);
}

ll lcm(ll a, ll b) {
    return a / gcd(a, b) * b;
}
int n , m , k;
int st, ed, level[200], cur[200];
struct node{
    int t, next, c;
}edge[4500];
int head[200], cnt = 0;
void add(int f, int t, int c)
{
    edge[cnt].t = t;
    edge[cnt].c = c;
    edge[cnt].next = head[f];
    head[f] = cnt ++;
}
struct e{
    int x, y;
}in[2500];
bool DinicBfs(int s, int e)
{
    mem(level,0);
    queue<int>q;
    q.push(s);
    level[s] = 1;
    while(!q.empty())
    {
        int root = q.front();
        q.pop();
        for(int i = head[root] ; i != -1 ; i = edge[i].next)
        {
            int v = edge[i].t, c = edge[i].c;
            if(!level[v] && c > 0)
            {
                level[v] = level[root] + 1;
                q.push(v);
            }
        }
    }
    return level[e] != 0;
}
int DinicDfs(int root , int flow)
{
    if(root == ed)
        return flow;
    int newflow , cost = 0;
    for(int& i = cur[root] ; i != -1 ; i = edge[i].next)
    {
        int v = edge[i].t, c = edge[i].c;
        if(level[v] == level[root] + 1 && c > 0 && (newflow = DinicDfs(v,min(c,flow-cost))))
        {
            cost += newflow;
            edge[i].c -= newflow;
            edge[i^1].c += newflow;
            if(cost == flow) break;
        }
    }
    return cost;
}
int Dinic()
{
    int ans = 0;
    while(DinicBfs(st,ed))
    {
        for(int i = 0 ; i <= n*3 ; i ++)
            cur[i] = head[i];
        while(int add = DinicDfs(st,INF))
            ans += add;
    }
    return ans;
}
int main(void)
{
#ifdef LOCAL
    freopen("data.in", "r", stdin);
    freopen("odata.out", "w", stdout);
#endif
    while(scanf("%d %d",&n, &m) == 2)
    {
        int ans = INF;
        char str[100];
        for(int i = 1; i <= m ; i ++)
        {
            int j;
            scanf("%s",str);
            for(in[i].x = 0, j = 1 ; str[j] != ',' ; j ++)
                in[i].x = in[i].x * 10 + str[j]-'0';
            for(in[i].y = 0, j ++ ; str[j] != ')' ; j ++)
                in[i].y = in[i].y * 10 + str[j]-'0';
            in[i].x ++ , in[i].y ++;
        }
        for(st = 1;st <= n;++ st)
            for(ed = 1;ed <= n;++ ed)
                if(st != ed)
                {
                    //除了拆点边容量为1,其他均为INF
                    memset(head,-1,sizeof(head));
                    cnt = 0;
                    for(int i = 1 ; i <= n; ++ i)
                        if(i == st || i == ed) add(i ,i+n,INF), add(i+n,i,0);
                        else add(i,i+n,1), add(i+n,i,0);
                    for(int i = 1 ; i <= m ; ++ i)
                    {
                        add(in[i].x+n,in[i].y,INF);
                        add(in[i].y,in[i].x+n,0);
                        add(in[i].y+n,in[i].x,INF);
                        add(in[i].x,in[i].y+n,0);
                    }
                    ans = min(ans,Dinic());
                }
        if(n <= 1 || ans == INF) ans = n;
        printf("%d\n",ans);
    }
    return 0;
}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1.下列哪一种的邻接矩阵是对称矩阵?( ) A.有向 B.无向图 C.AOV网 D.AOE网 2.在边表示活动的AOE网中,关键活动的最迟开始时间( ) 最早开始时间。 A.> B.= D.= 3.带权有向G用邻接矩阵A存储,则顶i的入度等于A中( ) 。 A.第i行非∞的元素之和 B.第i列非∞的元素之和 C.第i行非∞且非0的元素个数 D.第i列非∞且非0的元素个数 4.在一个无向图中,所有顶的度数之和等于所有边数的( ) 倍。 A.1/2 B. 1 C. 2 D. 4 5.对于一个具有n个顶无向图,若采用邻接矩阵存储,则该矩阵的大小是(D) A.n B.(n-1)2 C.n-1 D.n2 6. 如下有关拓扑序列的叙述,( ) 不对。 A. 拓扑序列包含了有向的全部顶 B. 有向有环一定没有拓扑序列 C. 有向无环不一定有拓扑序列 D. 拓扑序列不一定唯一 7. 对于描述工程的AOE网,( ) 说法正确。 A. 网中唯一的出度为零的顶,称为源 B. 网中唯一的入度为零的顶,称为汇 C. 关键路径是源到汇的最短路径 D. 关键路径可能有多条 8. 最小生成树指的是( ) 。 A. 由连通网所得到的边数最少的生成树 B. 由连通网所得到的顶数相对较少的生成树 C. 连通网中所有生成树中权值之和为最小的成生树 D. 连通网的极小连通 9.一个有向,共有n条弧,则所有顶的度的总和为( ) 。 A.2n B.n C.n-1 D.n/2 二、填空题(每空3分,共9分)。 1.有n个顶连通至少有___条边。有n个顶无向图至多有 条边。 2. 的广度优先遍历算法中用到辅助队列,每个顶最多进队 次。 3.在一个具有n个顶的有向完全中包含有 条边。 三、综合题(共23分)(答案可以在纸上笔画然后拍照贴到文档的方式)。 1. (共7分)无向网如下: (1) 给出如所示网的邻接矩阵表示(3分): (2) 画出最小生成树(4分): 2 .(共8分)已知一个连通所示,试给出的邻接矩阵和邻接链表存储示意。 (1) 邻接矩阵存储示意为(4分): (2) 邻接链表存储示意为(4分): 3. (共8分)如所示的带权无向图,请用克鲁斯卡尔算法给出最小生成树的解过程。 用克鲁斯卡尔算法最小生成树的过程为:

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值