poj1087&&hdu1526 最大流
多源多汇。
比较明显的建图。对于电器,可以从源点与各个电器相连,容量为1,表示这个电器有1个,然后对于各种接头,那可以各个接头与汇点相连,容量为1,表示每个接头只能用一次。
然后对于能够相互转换的接头,其容量为无穷,文中写到转换器可以无穷使用。然后对于电器和其使用的接头,相连,容量为1表示该电器使用该接头。然后求一次最大流,表示最多可以使用的电器,然后见一下即可。
由于字符串,用map搞了半天。
poj 79MS
hdu 15MS
下面是poj代码:
#include<stdio.h> #include<string.h> #include<string> #include<map> #include<queue> #include<iostream> #define maxn 500 #define INF 9999999 using namespace std; map<string,int>d,num; int mp[maxn][maxn],n,m,fn,vis[maxn],F;//fn表示插头的种类数 string name,s1,s2; string s[120],fname[120]; int min(int x,int y) {return x<y?x:y;} void makemap() { int i,j; for(i=0;i<m;i++) { mp[d[s[i]]][d[fname[i]]]=1; //printf("%d %d\n",d[s[i]],d[fname[i]]); } for(i=1;i<=F;i++) { mp[i][n+1]=1; } for(i=fn+1;i<=n;i++) { mp[0][i]=1; } } int BFS() { int i,j; queue<int>q; memset(vis,-1,sizeof(vis)); vis[0]=0; q.push(0); while(!q.empty()) { int t=q.front(); q.pop(); for(i=0;i<=n+1;i++) { if(vis[i]<0&&mp[t][i]) { vis[i]=vis[t]+1; q.push(i); } } } if(vis[n+1]>0) return 1; return 0; } int dfs(int u,int low) { int i,j,a; if(n+1==u) return low; for(i=0;i<=n+1;i++) { if(vis[i]==vis[u]+1&&mp[u][i]) { a=dfs(i,min(low,mp[u][i])); if(!a)continue; mp[u][i]-=a; mp[i][u]+=a; return a; } } return 0; } int main() { int t,i,j,cou=1; while(scanf("%d",&F)!=EOF) { memset(mp,0,sizeof(mp)); for(i=0;i<F;i++) { cin>>name; d[name]=cou++; } scanf("%d",&m); for(i=0;i<m;i++) { cin>>s[i]; cin>>fname[i]; if(!d[fname[i]]) d[fname[i]]=cou++; } fn=cou-1; //printf("%d\n",fn); for(i=0;i<m;i++) { if(!d[s[i]]) d[s[i]]=cou++; } n=cou-1; makemap(); //printf("%d\n",n); scanf("%d",&t); for(i=0;i<t;i++) { cin>>s1>>s2; mp[d[s1]][d[s2]]=INF; } //printf("%d\n",d[s[0]]); /*for(i=0;i<=n+1;i++) { for(j=0;j<=n+1;j++) { printf("%d ",mp[i][j]); } printf("\n"); }*/ int ans=0; while(BFS()) { while(1) { int a=dfs(0,INF); if(!a)break; ans+=a; } } printf("%d\n",m-ans); } }
hdu比较坑,爆栈,然后加了一句话#pragma comment(linker, "/STACK:1024000000,1024000000")
#pragma comment(linker, "/STACK:1024000000,1024000000") #include<stdio.h> #include<string.h> #include<string> #include<map> #include<queue> #include<iostream> #define maxn 500 #define INF 9999999 using namespace std; map<string,int>d,num; int mp[maxn][maxn],n,m,fn,vis[maxn],F;//fn表示插头的种类数 string name,s1,s2; string s[120],fname[120]; int min(int x,int y) {return x<y?x:y;} void makemap() { int i,j; for(i=0;i<m;i++) { mp[d[s[i]]][d[fname[i]]]=1; //printf("%d %d\n",d[s[i]],d[fname[i]]); } for(i=1;i<=F;i++) { mp[i][n+1]=1; } for(i=fn+1;i<=n;i++) { mp[0][i]=1; } } int BFS() { int i,j; queue<int>q; memset(vis,-1,sizeof(vis)); vis[0]=0; q.push(0); while(!q.empty()) { int t=q.front(); q.pop(); for(i=0;i<=n+1;i++) { if(vis[i]<0&&mp[t][i]) { vis[i]=vis[t]+1; q.push(i); } } } if(vis[n+1]>0) return 1; return 0; } int dfs(int u,int low) { int i,j,a; if(n+1==u) return low; for(i=0;i<=n+1;i++) { if(vis[i]==vis[u]+1&&mp[u][i]) { a=dfs(i,min(low,mp[u][i])); if(!a)continue; mp[u][i]-=a; mp[i][u]+=a; return a; } } return 0; } int main() { int t,i,j,cou,ft; scanf("%d",&ft); while(ft--) { cou=1; scanf("%d",&F); memset(mp,0,sizeof(mp)); d.clear(); for(i=0;i<F;i++) { cin>>name; d[name]=cou++; } scanf("%d",&m); for(i=0;i<m;i++) { cin>>s[i]; cin>>fname[i]; if(!d[fname[i]]) d[fname[i]]=cou++; } fn=cou-1; //printf("%d\n",fn); for(i=0;i<m;i++) { if(!d[s[i]]) d[s[i]]=cou++; } n=cou-1; makemap(); //printf("%d\n",n); scanf("%d",&t); for(i=0;i<t;i++) { cin>>s1>>s2; mp[d[s1]][d[s2]]=INF; } //printf("%d\n",d[s[0]]); /*for(i=0;i<=n+1;i++) { for(j=0;j<=n+1;j++) { printf("%d ",mp[i][j]); } printf("\n"); }*/ int ans=0; while(BFS()) { while(1) { int a=dfs(0,INF); if(!a)break; ans+=a; } } printf("%d\n",m-ans); if(ft)printf("\n"); } }