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
****************************************************************/