poj 1087 网络流

仍是最大流。

map很好用啊,自己写的change函数就TLE了,直接拿map来映射就行。。。

转换器之间边权值为MX。

VS到用电器之间权值为1,用电器到插头之间权值为1,提供的插座到VT之间权值为1.


#include<stdio.h>
#include<string.h>
#include<map>
#include<string>
#define MX 100000
using namespace std;
int h,n1,n2,n3,pre[700],queue[10000],named[30],mapp[700][700],vt,vs,deep[700];
char nam[1000][30];
struct point{
	char name[100];
}it[1005];
map<string,int>mp;
int change(char s[]){
	for(int i=1;i<h;i++){
		if(strcmp(s,nam[i])==0){
			return i;
		}
	}
	strcpy(nam[h++],s);
	return h-1;
}
int min(int a,int b){
	return a<b?a:b;
}
bool bfs(){    //构建增广路
	memset(deep,-1,sizeof(deep));
	int qe=1,qs=0;
	queue[qs]=vs;
	deep[0]=0;
	while(qs<qe){
		int v=queue[qs++];
		for(int i=1;i<=vt;i++){
			if(deep[i]==-1&&mapp[v][i]){
				deep[i]=deep[v]+1;
				queue[qe++]=i;
			}
		}
	}
	if(deep[vt]==-1){
		return false;
	}
	return true;
}
int dfs(int v,int num){  //Dinic,返回流量,num为从上一个流来的流量。v为上一个点。
	int numcy=num;
	if(v==vt){
		return num;
	}
	else{
		for(int i=0;i<=vt;i++){
			if(mapp[v][i]&&deep[i]==deep[v]+1){
				int p=min(num,mapp[v][i]);
				int t=dfs(i,p);
				mapp[v][i]-=t;
				mapp[i][v]+=t;
				num-=t;
		//		printf("! %d vt=%d t=%d\n",i,vt,t);
			}
		}
	}
	return numcy-num;
}
int main(){
	while(scanf("%d",&n1)!=EOF){
		memset(mapp,0,sizeof(mapp));
		h=1;
		mp.clear();
		int sn=0;
		int ans=0;
		for(int i=0;i<n1;i++){
			char t[5];
			scanf("%s",t);
			if(mp.count(t)==0){
				mp[t]=++sn;
			}
			named[i]=mp[t];
	//		printf("! k=%d\n",k);
		}
		scanf("%d",&n2);
		for(int i=1;i<=n2;i++){
			char t[5];
			scanf("%s%s",it[i].name,t);
			if(mp.count(t)==0){
				mp[t]=++sn;
			}
			mapp[i][mp[t]+n2]=1;
			mapp[0][i]=1;
//			printf("!! k=%d\n",k);
		}
		vs=0;
		scanf("%d",&n3);
		for(int i=0;i<n3;i++){
			char t1[5],t2[5];
			scanf("%s%s",t1,t2);
			if(mp.count(t1)==0){
				mp[t1]=++sn;
			}
			if(mp.count(t2)==0){
				mp[t2]=++sn;
			}
			mapp[mp[t1]+n2][mp[t2]+n2]=MX;
		}
		vt=n2+sn+1;
		for(int i=0;i<n1;i++){
			mapp[named[i]+n2][vt]=1;
		}
		int flow=0;
/*		for(int i=0;i<=vt;i++){
			for(int j=0;j<=vt;j++){
				printf("%d ",mapp[i][j]);
			}
			printf("\n");
		}*/
		while(bfs()){
			ans+=dfs(vs,MX);
//		printf("! ans=%d\n",ans);
		}
		printf("%d\n",n2-ans);
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值