http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1788
注意门与门之间可能有多条路!!
输入可以连通就相应的边就 + INF
判断 map[i][j]>=inf 反面就又map[j][i]=map[i][j]/inf 容量的路
算最大流,if flow>=inf 则 入侵
else flow
View Code
#include<stdio.h>
#include<string.h>
int map[39][39];
const int inf=100000000;
const int MAXN=39;
int max_flow(int n,int mat[][MAXN],int source,int sink)
{
int v[MAXN],c[MAXN],p[MAXN],ret=0,i,j;
for(;;){
for(i=0;i<n;i++)
v[i]=c[i]=0;
for(c[source]=inf;;){
for(j=-1,i=0;i<n;i++)
if(!v[i]&&c[i]&&(j==-1||c[i]>c[j]))
j=i;
if(j<0)return ret;
if(j==sink)break;
for(v[j]=1,i=0;i<n;i++)
if(mat[j][i]>c[i]&&c[j]>c[i])
c[i]=mat[j][i]<c[j]?mat[j][i]:c[j],p[i]=j;
}
for(ret+=j=c[i=sink];i!=source;i=p[i])
mat[p[i]][i]-=j,mat[i][p[i]]+=j;
}
return ret;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
memset(map,0,sizeof(map));
int m,n,i,j,k;
char temp[9];
scanf("%d%d",&n,&m);
int ss=0,tt=n+1;
map[m+1][tt]=inf;
for(i=1;i<=n;i++)
{
scanf("%s",temp);
if(temp[0]=='I')
{
scanf("%d",&k);
map[ss][i]=inf;
for(j=1;j<=k;j++)
{
int to;
scanf("%d",&to);
to++;
map[i][to]+=inf;//注意可以有多条边
}
}
else
{
scanf("%d",&k);
for(j=1;j<=k;j++)
{
int to;
scanf("%d",&to);
to++;
map[i][to]+=inf;
}
}
}
for(i=1;i<=n;i++){
for(j=1;j<=n;j++){
if(map[i][j]>=inf)
{
if(map[j][i]==0)
map[j][i]=map[i][j]/inf;
}
}
}
int flow=max_flow(n+2,map,ss,tt);
if(flow>=inf)
printf("PANIC ROOM BREACH\n");
else
printf("%d\n",flow);
}
return 0;
}