1. 程式人生 > >poj 1966 Cable TV Network

poj 1966 Cable TV Network

return OS tmp 自然 std n) 最小 思路 res

Description:

給定一張無向圖,問至少去掉多少個點, 可以使圖不連通。點數N ≤ 50

思路:先固定一個點s,然後枚舉另一個點t,然後求最少要割掉幾個點使兩點不連通

  自然聯系到最小割,但最小割是割邊,割點呢?只要把每個點拆成兩個點,割去一個點等價於在網絡中斷開其拆成的兩點中間的邊。

所以將原無向圖中的邊權設為正無窮大,然後將每個點對之間的邊權設為1,然後就能用最小割寫了

#include<iostream>
#include<cstring>
#include<queue>
#include<cstdio>
using
namespace std; const int N = 110; const int M = 10010; const int INF = 1e9; int head[N],now; struct edges{ int to,next,w; }edge[M<<1]; void add(int u,int v,int w){ edge[++now] = {v,head[u],w}; head[u] = now;} int n,m,s,t,dep[N],ans; void init(){ memset(edge,0,sizeof(edge)); now = 1
; memset(head,0,sizeof(head)); memset(dep,0,sizeof(dep)); } int dinic(int x,int flow){ if(x == t) return flow; int rest = flow, k; for(int i = head[x]; i; i = edge[i].next){ int v = edge[i].to; if(edge[i].w && dep[v] == dep[x] + 1){ k
= dinic(v,min(rest, edge[i].w)); if(!k) dep[v] = 0; edge[i].w -= k; edge[i ^ 1].w += k; rest -= k; } } return flow - rest; } bool bfs(){ memset(dep,0,sizeof(dep)); queue<int> q; q.push(s); dep[s] = 1; while(!q.empty()){ int x = q.front(); q.pop(); for(int i = head[x]; i; i = edge[i].next){ int v = edge[i].to; if(edge[i].w && !dep[v]){ q.push(v); dep[v] = dep[x] + 1; if(v == t) return 1; } } } return 0; } struct input{ int x,y; }inp[M]; int main(){ while(scanf("%d%d",&n,&m) != EOF){ ans = INF; int x,y; for(int i = 1; i <= m; i++){ scanf(" (%d,%d)",&x,&y); x++, y++; inp[i] = {x,y}; // add(x,y+n,INF);add(y+n,x,0); } if(n == 1){ puts("1"); continue; } s = 1; for(t = 2; t <= n; t++){ //枚舉一個終點 init(); for(int i = 1; i <= m; i++){ add(inp[i].y + n,inp[i].x, INF); //拆點連邊 add(inp[i].x,inp[i].y + n, 0); add(inp[i].x + n,inp[i].y, INF); add(inp[i].y,inp[i].x + n, 0); } int x,y; for(int i = 1; i <= n; i++) if(i != s && i != t) add(i,i+n,1), add(i+n,i,0); //把所對拆點之間的邊權設為1 int tmp = 0, maxflow = 0; s += n; while(bfs()) //最大流最小割 while(tmp = dinic(s,INF)) maxflow += tmp; ans = min(ans,maxflow); s -= n; } if(ans == INF) printf("%d\n",n); else printf("%d\n",ans); } return 0; }

poj 1966 Cable TV Network