标签:
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 16083 | Accepted: 5513 |
Description
Input
Output
Sample Input
4 A B C D 5 laptop B phone C pager B clock B comb X 3 B X X A X D
Sample Output
1
【题意】有n个插座,m个电器,每个电器都对应一个插头,k个转换器,s1 s2表示插座s2可以转换成s1,
开始提供的插座只有一个插口,转换器有无数个,问最少有几个电器无法使用。
【分析】这就是个最大流问题,关键在于建图。定义一个超级源点,超级汇点,源点指向n个插座,电器
指向汇点,插座指向对应的电器,容量均为1,s2指向s1,容量为无穷大,Dinic求最大流。还有就是
这个题目数据范围有问题,定105RE,后看讨论改的805.
#include <iostream> #include <cstring> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <time.h> #include <string> #include <map> #include <stack> #include <vector> #include <set> #include <queue> #define inf 0x3f3f3f3f #define mod 10000 typedef long long ll; using namespace std; const int N=805; const int M=300005; int power(int a,int b,int c){int ans=1;while(b){if(b%2==1){ans=(ans*a)%c;b--;}b/=2;a=a*a%c;}return ans;} struct man { int c,f; }w[N][N]; int dis[N],n,m,k; int s,ans,cnt; int link; map<string,int>p; bool bfs() { queue<int>q; memset(dis,0,sizeof(dis)); q.push(s); dis[s]=1; while(!q.empty()){ int v=q.front();q.pop(); for(int i=0;i<=cnt;i++){ if(!dis[i]&&w[v][i].c>w[v][i].f){ q.push(i); dis[i]=dis[v]+1; } } if(v==1) return true; } return false; } int dfs(int cur,int cp) { if(cur==1)return cp; int tmp=cp,tt; for(int i=0;i<=cnt;i++){ if(dis[i]==dis[cur]+1 && tmp &&w[cur][i].c>w[cur][i].f){ tt=dfs(i,min(w[cur][i].c-w[cur][i].f,tmp)); w[cur][i].f+=tt; w[i][cur].f-=tt; tmp-=tt; } } return cp-tmp; } void dinic() { ans=0; while(bfs())ans+=dfs(s,inf); } int main(){ string str,_str; while(~scanf("%d",&n)){ memset(w,0,sizeof(w)); p.clear(); cnt=1; s=0; while(n--){ cin>>str; p[str]=++cnt; w[0][p[str]].c=1; } cin>>m; int M=m; while(m--){ cin>>str>>_str; p[str]=++cnt; if(!p[_str])p[_str]=++cnt; w[p[str]][1].c=1; w[p[_str]][p[str]].c=1; } cin>>k; while(k--){ cin>>str>>_str; if(!p[str])p[str]=++cnt; if(!p[_str])p[_str]=++cnt; w[p[_str]][p[str]].c=inf; } dinic(); cout<<M-ans<<endl; } return 0; }
标签:
原文地址:http://www.cnblogs.com/jianrenfang/p/5832615.html