題目連接:https://vjudge.net/problem/POJ-1087node
題目:有n個插座,插座上只有一個插孔,有m個用電器,每一個用電器都有插頭,它們的插頭能夠同樣,ios
有k個插孔轉化器, a b 的意思就是 能夠把 b類的插孔變成a類的插孔,那麼a類對於的插頭就能夠用這個插孔充電了。ui
問:沒插孔的用電器最少有幾個。spa
思路:源點->插座->用電器->匯點。.net
由於插座之間能夠相互轉化,可能A,B,C,D均可以變成E類的插座,因此插座之間的流應該爲INF,其餘的邊流都是1,起到限流的做用。code
編號比較麻煩,能夠用map進行標記,編號。blog
這裏N = 1100 ,以前寫的代碼N = 410,wa了 而後我N = 1100的過了以後,wa的代碼直接複製提交到POJ竟然過了。。。我是矇蔽的,很無奈。get
#include <iostream> #include <cstdio> #include <map> #include <string> #include <queue> #include <algorithm> #include <vector> using namespace std; const int N = 1100,INF = (int)1e9; int id,tot,s,t,all; int head[N],lev[N],cur[N]; map<string,int > mp; vector<string > ve[2]; queue<int > que; struct node{ int to,nxt,flow; }e[N*N]; inline void add(int u,int v,int flow){ e[tot].to = v; e[tot].flow = flow; e[tot].nxt = head[u]; head[u] = tot++; e[tot].to = u; e[tot].flow = 0; e[tot].nxt = head[v]; head[v] = tot++; } inline bool ID(char* name){ if(mp.count(name)) return true; else return false; } void build_map(){ for(int i = 0; i <= 1000; ++i) head[i] = -1; tot = 0; int n,m,k; char name1[30],name2[30]; scanf("%d",&n); for(int i = 1; i <= n; ++i){ scanf("%s",name1); if(!ID(name1)) mp[name1] = ++id; ve[0].push_back(name1); } //插座到用電器 scanf("%d",&m); all = m; for(int i = 1; i <= m; ++i){ scanf("%s%s",name1,name2); if(!ID(name1)) mp[name1] = ++id; if(!ID(name2)) mp[name2] = ++id; add(mp[name2],mp[name1],1); ve[1].push_back(name1); } //插座之間 scanf("%d",&k); for(int i = 1; i <= k; ++i){ scanf("%s%s",name1,name2); if(!ID(name1)) mp[name1] = ++id; if(!ID(name2)) mp[name2] = ++id; add(mp[name2],mp[name1],INF); } //源點到插座 s = 0, t = ++id; int num[2] = {ve[0].size(), ve[1].size()}; for(int i = 0; i < num[0]; ++i){ add(s,mp[ve[0][i]],1); } //用電器到匯點 for(int i = 0; i < num[1]; ++i){ add(mp[ve[1][i]],t,1); } } void show(){ cout << "id ====== " << id << endl; for(int i = 0; i <= id; ++i){ printf("當前點爲 %d 相關聯的點:",i); for(int o = head[i]; ~o; o = e[o].nxt){ printf("%d 流量爲 %d ",e[o].to,e[o].flow); }cout << endl; } } bool bfs(int s,int t){ for(int i = s; i <= t; ++i) lev[i] = 0; while(!que.empty()) que.pop(); lev[s] = 1; que.push(s); while(!que.empty()){ int u = que.front(); que.pop(); for(int o = head[u]; ~o; o = e[o].nxt){ int v = e[o].to; if(!lev[v] && e[o].flow){ lev[v] = lev[u] + 1; if(v == t) return true; que.push(v); } } } return false; } int dfs(int now,int flow,int t){ if(now == t) return flow; int sum = 0,tmp; for(int o = cur[now]; ~o; o = e[o].nxt){ int to = e[o].to; if((lev[to] == lev[now] +1) && e[o].flow && (tmp = dfs(to,min(flow-sum,e[o].flow),t))){ e[o].flow -= tmp; e[o^1].flow += tmp; if((sum += tmp) == flow) return sum; } } return sum; } int mf(int s,int t){ int _mf = 0; while(bfs(s,t)){ for(int i = s; i <= t; ++i) cur[i] = head[i]; _mf += dfs(s,INF,t); } return _mf; } int main(){ build_map(); // show(); int _mf = mf(s,t); printf("%d\n",all -_mf); return 0; }