Problem : Cable TV Network
Description : 求一个无向图的点连通度。
Solution : 拆点+最小割。这几乎是一个模板题。但是数据太逗比了,题中说了:“ Follow m data pairs (u,v), u < v”但是就是存在(1,1)这种类型的边。WA了一天才发现这个问题,如果存在这种边,就会导致拆点失败!。说说如何求无向图的点连通度吧。我们可以用网络最大流来做,首先要拆点连一条权值为1的边,如果删掉这条边也就等于删掉了这个点,那么直接对这个图求最小割就好了。
Code(C++) :
#include
#include
#include
#include
#include
#define MIN(a,b) ((a)>(b)? (b):(a))
using namespace std;
const int SIZE=50*2+50;
const int INF=0x3f3f3f3f;
struct Node{
int u,v;
int cap;
Node(){}
Node(int U,int V,int Cap):
u(U),v(V),cap(Cap){}
};
int src,des;
vector<int> G[SIZE];
Node e[SIZE*SIZE/2];
int d[SIZE];
int cur[SIZE];
int top;
int N,M;
bool MAP[SIZE][SIZE];
void addedge(int u,int v,int cap)
{
G[u].push_back(top);
e[top++]=Node(u,v,cap);
G[v].push_back(top);
e[top++]=Node(v,u,0);
}
void build()
{
int i,j;
for(i=0;i0;
for(i=1;i<=N;i++)
addedge(i+N,i,1);
for(i=1;i<=N;i++)
for(j=1;j<=N;j++)
if(MAP[i][j])
addedge(i,j+N,INF);
}
bool bfs(int src,int des)
{
memset(d,-1,sizeof(d));
queue<int> que;
que.push(src);
d[src]=0;
while(!que.empty()){
int now=que.front();
que.pop();
for(int i=0;iif(tmp.cap>0&&d[tmp.v]==-1)
d[tmp.v]=d[now]+1,
que.push(tmp.v);
}
}
return d[des]>=0;
}
int dfs(int t,int sum,int des)
{
if(t==des||!sum)
return sum;
int flow=0,f;
for(int &i=cur[t];iif(d[tmp.v]==d[t]+1&&(f=dfs(tmp.v,MIN(sum,tmp.cap),des))>0){
tmp.cap-=f;
e[G[t].at(i)^1].cap+=f;
sum-=f;
flow+=f;
if(!sum)
break;
}
}
return flow;
}
int DINIC(int src,int des)
{
int sum=0;
while(bfs(src,des)){
memset(cur,0,sizeof(cur));
sum+=dfs(src,INF,des);
}
return sum;
}
int main()
{
//freopen("in.data","r",stdin);
while(~scanf("%d%d",&N,&M)){
int i,j;
int ans=N;
int x,y;
memset(MAP,false,sizeof(MAP));
for(i=0;iscanf(" (%d,%d)",&x,&y);
++x,++y;
if(x==y)
continue;
MAP[x][y]=MAP[y][x]=true;
}
for(i=1;i<=N;i++)
for(j=i+1;j<=N;j++){
build();
addedge(0,i,INF);
addedge(j+N,N*2+1,INF);
int tmp=DINIC(0,2*N+1);
ans=MIN(ans,tmp);
}
printf("%d\n",ans);
}
return 0;
}