poj 1149

网络流,重在建图(注意重边)。

代码:

#include<iostream>
#include<fstream>
#include<queue>

using namespace std;

int n;
int c[105][105],pre[105],f[105][105];
int d[105],flow;
int v[105];


typedef struct e{
	int data;
	e *next;
}e;

e edge[105];


int build(){
	int i,j,k;
	queue<int> q;
	q.push(1);
	memset(d,0,sizeof(d));
	d[1]=1;
	while(!q.empty())
	{
		i=q.front();
		q.pop();
		e *p=edge[i].next;
		while(p)
		{
			j=p->data;
			if(d[j]==0&&c[i][j]>f[i][j])
			{
				d[j]=d[i]+1;
				if(j==n) return 1;
				q.push(j);
			}
			p=p->next;
		}
	}
	return 0;
}

int find(int m,int minw){
	int i,j,k;
	if(m==n) return minw;
	v[m]=1;
	e *p=edge[m].next;
	while(p)
	{
		i=p->data;
		if(c[m][i]>f[m][i]&&d[i]==d[m]+1&&v[i]==0)
		{
			j=find(i,min(minw,c[m][i]-f[m][i]));
			if(j)
			{
				f[m][i]+=j;
				f[i][m]=-1*f[m][i];
				return j;
			}
		}
		p=p->next;
	}
	return 0;
}


int solve(){
	int i,j,k;
	flow=0;
	memset(f,0,sizeof(f));
	while(build())
		while(1){
			memset(v,0,sizeof(v));
			i=10000000;
			k=find(1,i);
			flow+=k;
			if(k==0) break;
		}
	return flow;
}

int value[1001];
int map[1001][101];
int cnt[1001];

void read(){
//	ifstream cin("in.txt");
	int i,j,k,s,t,m;
	cin>>n>>m;
	for(i=1;i<=n;i++)
		cin>>value[i];

	for(i=1;i<=m;i++)
	{
		cin>>k;
		for(j=1;j<=k;j++)
		{
			cin>>s;
				cnt[s]++;
				map[s][cnt[s]]=i;
				if(cnt[s]!=1)
					c[map[s][cnt[s]-1]+1][i+1]=1000000;
				else
					c[map[s][cnt[s]-1]+1][i+1]+=value[s];
					
				e *p=new e;
				p->data=i+1;
				p->next=edge[map[s][cnt[s]-1]+1].next;
				edge[map[s][cnt[s]-1]+1].next=p;
				
				e *q=new e;
				q->data=map[s][cnt[s]-1]+1;
				q->next=edge[i+1].next;
				edge[i+1].next=q;
		}
		cin>>k;
		c[i+1][m+2]=k;
		e *p=new e;
		p->data=m+2;
		p->next=edge[i+1].next;
		edge[i+1].next=p;

		e *q=new e;
		q->data=i+1;
		q->next=edge[m+2].next;
		edge[m+2].next=q;
	}
	n=m+2;
	solve();
	cout<<flow<<endl;

}

int main(){
	read();
	return 0;
}

posted on 2011-03-14 12:16  宇宙吾心  阅读(384)  评论(0)    收藏  举报

导航