http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1167
题意是说水管道有一个入口..多个出口..以及多个分流点...有些分流点之间的管道是有闸的..可以将该管道给关掉..现在有T(T<=10)次提问..问只需编号为X的出口出水..问最少需要关掉多少闸...
实际上就是说..从起点到终点..最少去掉多少允许去掉的边..使得起点到不了终点..不就是最小割的模型么..而最小割=最大流..so...让有闸的边容量为1..其他无闸的边设为一个很大的容量...跑出的最大流就是结果..当然若是一个不合理的大数..则说明是No solution!...
这题在比赛的时候最后一刻过了样例..不过还是没交得上去..赛后提交结果超时了..在CSU-ACM群里问了一句..大牛说缩点..再观察了下题目..确实..题目给的前L条边根本没必要做..利用这些边以及并查集将点合并..后面的K条才需做边...
Program:
#include<iostream> #include<stdio.h> #include<string.h> #include<math.h> #include<queue> #define oo 2000000000 #define ll long long using namespace std; struct node { int x,y,c,next; }LINE[10001],line[10001]; int _link[2100],_LINK[2100],ans,dis[2100],s,e,way[2100],num,father[2100]; queue<int> myqueue; bool BFS() { int i,h,k; memset(dis,0,sizeof(dis)); while (!myqueue.empty()) myqueue.pop(); myqueue.push(s); dis[s]=1; while (!myqueue.empty()) { h=myqueue.front(); myqueue.pop(); k=_link[h]; while (k) { if (line[k].c && !dis[line[k].y]) { dis[line[k].y]=dis[h]+1; myqueue.push(line[k].y); } k=line[k].next; } } return dis[e]; } bool DFS(int h,int MaxFlow) { int i,k; if (h==e) { ans+=MaxFlow; for (i=1;i<=num;i++) { k=way[i]; line[k].c-=MaxFlow; if (line[k+1].x==line[k].y && line[k+1].y==line[k].x) k++; else k--; line[k].c+=MaxFlow; } return true; } k=_link[h]; while (k) { if (line[k].c && dis[line[k].y]-dis[h]==1) { way[++num]=k; if (DFS(line[k].y,min(line[k].c,MaxFlow))) return true; num--; } k=line[k].next; } return false; } void MaxFlow() { ans=-1; if (s==e) return; ans=0; while (BFS()) { num=0; DFS(s,10000); } return; } int getfather(int k) { if (father[k]==k) return k; return father[k]=getfather(father[k]); } int main() { int i,h=0,M,N,L,K,T,G,x,y; while (~scanf("%d%d%d%d%d",&M,&N,&L,&K,&T)) { memset(_LINK,0,sizeof(_LINK)); N+=M; for (i=0;i<N;i++) father[i]=i; for (i=1;i<=L;i++) { scanf("%d%d",&x,&y); father[getfather(x)]=getfather(y); } N+=M; for (i=0;i<N;i++) getfather(i); G=0; for (i=1;i<=K;i++) { scanf("%d%d",&x,&y); x=father[x]; y=father[y]; if (x==y) continue; G++; LINE[G].x=x; LINE[G].y=y; LINE[G].c=1; LINE[G].next=_LINK[LINE[G].x]; _LINK[LINE[G].x]=G; G++; LINE[G].x=y; LINE[G].y=x; LINE[G].c=1; LINE[G].next=_LINK[LINE[G].x]; _LINK[LINE[G].x]=G; } if (h) printf("\n"); h++; s=father[0]; while (T--) { scanf("%d",&e); e=father[e]; for (i=1;i<=G;i++) line[i]=LINE[i]; for (i=0;i<N;i++) _link[i]=_LINK[i]; MaxFlow(); if (ans<0) printf("No solution!\n"); else printf("%d\n",ans); } } return 0; } /************************************************************** Problem: 1167 User: zzyzzy12 Language: C++ Result: Accepted Time:120 ms Memory:1568 kb ****************************************************************/