POJ 1087

http://poj.org/problem?id=1087

額,下面的題意和圖片什麼的都是我貼過來的(呵呵,實在太難理解了)

代碼還是自己寫滴

題意:

有插座用電器和適配器,用電器有插頭,適配器本身有一個插孔和插頭,它的作用是可以把別的插頭插入到適合該適配器插孔的適配器,然後就可以用適配器的插頭接到適合的插座,相當於轉換插頭的作用。每個插座只能插入一個插頭。3種東西都最多有100個,但是任一種適配器可以有無限個。問最後最少能剩下幾個用電器不能用上電。

思路:

每一種插頭看成一個點,注意是每一種,每一個用電器看成一個點,注意是每一個,然後構圖。用電器可以插入對應的插座,所以該用電器這個點可以和該插座對應的插頭種類這個點連線,權爲1。由於適配器有無數個,所以適配器的插孔對應的插頭和適配器的插頭連線,權爲INF。自取源點匯點,令源點和所有用電器連線,權爲1n個插座對應的插頭與匯點相連,權爲1.sample爲例,繪圖如下:

 

#include<stdio.h>
#include<string.h>
#include<map>
#include<string>
#include<vector>
#define M 800
#define INF 0xfffffff
using namespace std;

map<string,int> mp;
vector<int> G[M];
int n,m,k;
int que[M];
int d[M];
int stack[M];
int g[M][M];
bool v[M];
//int no=0;

bool BFS(int s,int t)
{
	int l=0,r=0;//no++;
	int i,p;
	memset(d,-1,sizeof(d));
	d[s]=0;
	que[r++]=s;
	while(l<r)
	{
		p=que[l++];
		for(i=0;i<G[p].size();i++)
		{
			int u=G[p][i];
			//printf("p=%d u=%d\n",p,u);
			if( g[p][u]>0 && d[u]==-1 )
			{
				d[u]=d[p]+1;//printf("no=%d p=%d u=%d\n",no,p,u);
				if(u==t) 
					return true;
				que[r++]=u;
			}
		}
	}
	return false;
}

int Dinic_Maxflow(int s,int t)
{
	int i,p;
	int nMinc;
	int minn;
	int ans=0;
	while(BFS(s,t))
	{
		int top=0,base=0;
		memset(v,false,sizeof(v));
		stack[top++]=s;
		v[s]=true;
		while(top>base)
		{
			p=stack[top-1];
			if(p==t)
			{
				minn=INF;
				for(i=1;i<top;i++)
				{
					int u=stack[i-1];
					int v=stack[i];
					if(g[u][v]<minn)
					{
						minn=g[u][v];
						nMinc=u;
					}
				}
				ans+=minn;
				for(i=1;i<top;i++)
				{
					int u=stack[i-1];
					int v=stack[i];
					g[u][v]-=minn;
					g[v][u]+=minn;
				}
				while(top>base && stack[top-1]!=nMinc)
					top--;
			}
			
			else 
			{
				for(i=0;i<G[p].size();i++)
				{
					int u=G[p][i];
					if( !v[u] && g[p][u]>0 && d[u]==d[p]+1 )
					{
						v[u]=true;
						stack[top++]=u;
						break;
					}
				}
				if(i==G[p].size())
					top--;
			}
		}
	}
	return ans;
}

int main()
{
	int index;
	int tot;
	char str[30],ss[30];
	while(scanf("%d",&n)!=EOF)
	{
		index=1;
		mp.clear();
		memset(G,0,sizeof(G));
		memset(g,0,sizeof(g));
		while(n--)
		{
			scanf("%s",str);
			mp[str]=index++;
			G[mp[str]].push_back(M-1);
			g[mp[str]][M-1]=1;//每個插座和匯點相連 
		}
		scanf("%d",&m);
		tot=m;
		while(m--)
		{
			scanf("%s%s",ss,str);
			mp[ss]=index++;
			g[0][mp[ss]]=1;//每個電器和源點相連 
			if(!mp[str])
			{
				mp[str]=index++;
			}
			G[0].push_back(mp[ss]);
			G[mp[ss]].push_back(mp[str]);
			G[mp[str]].push_back(mp[ss]);
			g[mp[ss]][mp[str]]=1;
		}
		scanf("%d",&k);
		while(k--)
		{
			scanf("%s%s",ss,str);
			if(!mp[str])
				mp[str]=index++;
			G[mp[ss]].push_back(mp[str]);
			G[mp[str]].push_back(mp[ss]);
			g[mp[ss]][mp[str]]=INF;//設配器有無數個 。。。真是無語,因爲這WA了無數次 
		}
		/*
		int i,j;
		for(i=0;i<index;i++)
		{	printf("%d:\n",i);
		for(j=0;j<G[i].size();j++)
				printf("<%d %d> ",G[i][j],g[i][G[i][j]]);
			printf("\n");
		}*/
		printf("%d\n",tot-Dinic_Maxflow(0,M-1));
	}
	return 0;
} 


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章