http://acm.nyist.net/JudgeOnline/problem.php?pid=489&&最大流

来源:互联网 发布:淘宝1钻店铺出售 编辑:程序博客网 时间:2024/05/22 10:51

很纠结怎么也想不到这一题用网络流来做,看来正如诸位神牛所说一切皆网络流,,,还是老话对于图论这类型的题来说,建图很重要,也是最难的,题意中文不解释。。

思路:我们规定哭泣的天使为1,微笑的为0,因为不确定矩阵中1的个数,我们用每行的编号对每列的列号建边,正好可以确定到每一个位置,然后构造出一个超级源点和一个超级汇点,让每行的行号作为顶点,分别和源点相连,连接成的边的容量为该行哭泣天使的人数,同时让每列的列号也作为顶点,分别与汇点相连,连接成的边的容量为该列哭泣天使的人数,最后求源点到汇的最大流,即最多可以确定有多少条从行到列的边。。。。。

#include<iostream>#include<algorithm>#include<string.h>#include<queue>#include<cstdio>#define M 602#define N 181205#define inf 0xfffffusing namespace std;typedef struct str{  int v;  int w;  int next;}Edge;Edge po[N];int head[M],Cur[M],lev[M],gap[M],flow[N],pre[N];int tot;void init(){memset(head,-1,sizeof(head));memset(lev,-1,sizeof(lev));memset(gap,0,sizeof(gap));memset(flow,0,sizeof(flow));tot=0;}void add(int a,int b,int c){po[tot].v=b;po[tot].w=c;po[tot].next=head[a];head[a]=tot++;po[tot].v=a;po[tot].w=0;po[tot].next=head[b];head[b]=tot++;}inline int Read(){char ch=getchar();while(ch<'0'||ch>'9') ch=getchar();int data=0;do{data=data*10+ch-'0';ch=getchar();  }while(ch>='0'&&ch<='9');return data;}void bfs(int t){queue<int>Q;Q.push(t);lev[t]=0;while(!Q.empty()){ int v=Q.front(); Q.pop(); gap[lev[v]]++; for(int i=head[v];i!=-1;i=po[i].next) { if(lev[po[i].v]==-1) { lev[po[i].v]=lev[v]+1; Q.push(po[i].v); } }}}int sap(int s,int t){int maxflow=0,low=inf,cur=s;memcpy(Cur,head,sizeof(head));while(lev[cur]<t){int &i=Cur[cur];for(;i!=-1;i=po[i].next){if(po[i].w>flow[i]&&lev[cur]==lev[po[i].v]+1){low=min(low,po[i].w-flow[i]);pre[po[i].v]=i;cur=po[i].v;if(cur==t){while(cur!=s){flow[pre[cur]]+=low;flow[pre[cur]^1]-=low;cur=po[pre[cur]^1].v;}maxflow+=low;low=inf;}break;}}if(i==-1){if(--gap[lev[cur]]==0) return maxflow;lev[cur]=inf;Cur[cur]=head[cur];for(int k=head[cur];k!=-1;k=po[k].next){if(po[k].w>flow[k]&&lev[cur]>lev[po[k].v]+1)  lev[cur]=lev[po[k].v]+1;}if(lev[cur]<inf) ++gap[lev[cur]];cur=s;}}return maxflow;}int main(){int Cas=Read();while(Cas--){       init();int m=Read();int n=Read();int row=0,col=0;for(int i=1;i<=m;++i){int a=Read();add(0,i,a);for(int j=1;j<=n;++j) add(i,m+j,1);row+=a;}for(int i=1;i<=n;++i) {int a=Read();add(m+i,m+n+1,a);col+=a;}if(col==row&&row==sap(0,m+n+1)) printf("Not Sure\n");else printf("Terrible\n");}return 0;}


原创粉丝点击