【BZOJ 1433】 [ZJOI2009]假期的宿舍

必须分为两个点!
因为每个人都只能睡自己朋友的位子
一个点的话 辐射状图就会Wa

建图时注意流量!! wa了很久!!~~~~~

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
#define MAXN 510
#define INF 100000000
bool b[MAXN];
int g[MAXN+2][MAXN+2];
int n,T,s,t;
int team[MAXN+10],head,tail;
int d[MAXN];
bool bfs()
{
    head=tail=0;memset(d,0,sizeof(d));
    d[s]=1;team[++tail]=s;
    while(head<tail)
    {
        int x=team[++head];
        for(int i=1;i<=n;i++)
            if(d[i]==0&&g[x][i])
                d[i]=d[x]+1,team[++tail]=i;
    }
    if(d[t]==0) return false;
    return true;
}
int dfs(int x,int mmin)
{
    if(x==t) return mmin;
    int tmp,f=0;
    for(int i=1;i<=n;i++)
        if(d[i]==d[x]+1&&g[x][i]&&(tmp=dfs(i,min(mmin,g[x][i]))))
        {
            g[x][i]-=tmp;
            g[i][x]+=tmp;
            mmin-=tmp,f+=tmp;
            if(mmin==0) return f;   
        }
    return f;
}
int main()
{
    scanf("%d",&T);
    while(T--)
    {
        memset(g,0,sizeof(g));
        memset(b,false,sizeof(b));
        scanf("%d",&n);
        s=n*2+1,t=n*2+2;
        int tmp,sum=0,ans=0;
        for(int i=1;i<=n;i++) 
		{
			scanf("%d",&tmp);
			if(tmp==0) g[s][i]=1,sum++;
			if(tmp==1) g[i][i+n]=1,g[i+n][t]=1,b[i]=true;
		}
        for(int i=1;i<=n;i++) 
		{
			scanf("%d",&tmp);
			if(b[i]&&tmp==0) g[s][i]=1,sum++;
		}
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
              {
			  	scanf("%d",&tmp);
			  	if(tmp==1) g[i][j+n]=1;
              }  
        n*=2;
        n+=2;
        while(bfs()) ans+=dfs(s,INF);
        if(ans==sum) printf("%s\n","^_^");
        else         printf("%s\n","T_T");
    }
    return 0;
}

邻接表版:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
#define MAXN 510
#define INF 100000000
bool b[MAXN];
int n,T,s,t;
int team[MAXN+10],head,tail;
int d[MAXN];
int tot=2,g[25000],num[25000],nnext[25000],flow[25000];
void Add(int x,int y,int z){nnext[tot]=g[x];g[x]=tot;num[tot]=y;flow[tot]=z;tot++;}
bool bfs()
{
	head=tail=0;memset(d,0,sizeof(d));
	d[s]=1;team[++tail]=s;
	while(head<tail)
	{
		int x=team[++head];
		for(int i=g[x];i;i=nnext[i])
		{
			int tmp=num[i];
			if(d[tmp]==0&&flow[i]!=0)
				d[tmp]=d[x]+1,team[++tail]=tmp;
		}
	}
	if(d[t]==0) return false;
	return true;
}
int dfs(int x,int mmin)
{
	if(x==t) return mmin;
	int tmp,f=0;
	for(int i=g[x];i;i=nnext[i])
		if(d[num[i]]==d[x]+1&&flow[i]!=0&&(tmp=dfs(num[i],min(mmin,flow[i]))))
		{
			flow[i]-=tmp;
			flow[i^1]+=tmp;
			mmin-=tmp,f+=tmp;
			if(mmin==0) return f;
			return tmp;	
		}
	return f;
}
int main()
{
	scanf("%d",&T);
	while(T--)
	{
		memset(b,false,sizeof(b));
		memset(g,0,sizeof(g));
		tot=2;
		scanf("%d",&n);
		s=n*2+1,t=n*2+2;
		int tmp,sum=0,ans=0;
		for(int i=1;i<=n;i++) 
		{
			scanf("%d",&tmp);
			if(tmp==0)
			{
				Add(s,i,1);
				Add(i,s,0);
				sum++;
			}
			if(tmp==1)
			{
				b[i]=true;
				Add(i,i+n,1);
				Add(i+n,i,0);
				Add(i+n,t,1);
				Add(t,i+n,0);
			}
		}
		for(int i=1;i<=n;i++)
		{
			scanf("%d",&tmp);
			if(b[i]==true&&tmp==0)
			{
				Add(s,i,1);
				Add(i,s,0);
				sum++;
			}
		} 
		for(int i=1;i<=n;i++)
			for(int j=1;j<=n;j++)
			{
				scanf("%d",&tmp);
				if(tmp==1)
				{
					Add(i,j+n,1);
					Add(j+n,i,0);
				}	
			}
		while(bfs()) ans+=dfs(s,INF);
		if(ans==sum) printf("%s\n","^_^");
		else         printf("%s\n","T_T");
	}
	return 0;
}
posted @ 2016-01-07 15:53  sxb_201  阅读(148)  评论(0编辑  收藏  举报