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

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

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

#include<iostream>
#include<algorithm>
#include<string.h>
#include<queue>
#include<cstdio>
#define M 602
#define N 181205
#define inf 0xfffff
using 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;
}


你可能感兴趣的:(c,网络,struct,SAP)