注意提交时使用G++,C++会compile error
题意:房间里有n个插座,每个插座都不一样。有m个不同的用电器,每个用电器有一个插头,每个插头只能插相对应的插座。再给k类转换器,每类转换器能把A插座转化成B插座,每类转换器无限个。求不能充电的用电器最少的个数。
注意转换器的插座和插头有可能原来没有,需要动态添加!
/* * Dinic algo for max flow * * This implementation assumes that #nodes, #edges, and capacity on each edge <= INT_MAX, * which means INT_MAX is the best approximation of INF on edge capacity. * The total amount of max flow computed can be up to LLONG_MAX (not defined in this file), * but each 'dfs' call in 'dinic' can return <= INT_MAX flow value. */ #include <stdio.h> #include <stdlib.h> #include <limits.h> #include <string.h> #include <assert.h> #include <queue> #include <vector> # include<iostream> # include<cstring> # include<map> #define N (300+2) //==================make sure this is the total node number! #define M (N*N+4*N) typedef long long LL; using namespace std; struct edge { int v, cap, next; }; edge e[M]; int head[N], level[N], cur[N]; int num_of_edges; //When there are multiple test sets, you need to re-initialize before each void dinic_init(void) { num_of_edges = 0; memset(head, -1, sizeof(head)); return; } int add_edge(int u, int v, int c1, int c2) { int& i=num_of_edges; assert(c1>=0 && c2>=0 && c1+c2>=0); // check for possibility of overflow e[i].v = v; e[i].cap = c1; e[i].next = head[u]; head[u] = i++; e[i].v = u; e[i].cap = c2; e[i].next = head[v]; head[v] = i++; return i; } void print_graph(int n) { for (int u=0; u<n; u++) { printf("%d: ", u); for (int i=head[u]; i>=0; i=e[i].next) { printf("%d(%d)", e[i].v, e[i].cap); } printf("\n"); } return; } //Find all augmentation paths in the current level graph This is the recursive version int dfs(int u, int t, int bn) { if (u == t) return bn; int left = bn; for (int i=head[u]; i>=0; i=e[i].next) { int v = e[i].v; int c = e[i].cap; if (c > 0 && level[u]+1 == level[v]) { int flow = dfs(v, t, min(left, c)); if (flow > 0) { e[i].cap -= flow; e[i^1].cap += flow; cur[u] = v; left -= flow; if (!left) break; } } } if (left > 0) level[u] = 0; return bn - left; } bool bfs(int s, int t) { memset(level, 0, sizeof(level)); level[s] = 1; queue<int> q; q.push(s); while (!q.empty()) { int u = q.front(); q.pop(); if (u == t) return true; for (int i=head[u]; i>=0; i=e[i].next) { int v = e[i].v; if (!level[v] && e[i].cap > 0) { level[v] = level[u]+1; q.push(v); } } } return false; } LL dinic(int s, int t) { LL max_flow = 0; while (bfs(s, t)) { memcpy(cur, head, sizeof(head)); max_flow += dfs(s, t, INT_MAX); } return max_flow; } int upstream(int s, int n) { int cnt = 0; vector<bool> visited(n); queue<int> q; visited[s] = true; q.push(s); while (!q.empty()) { int u = q.front(); q.pop(); for (int i=head[u]; i>=0; i=e[i].next) { int v = e[i].v; if (e[i].cap > 0 && !visited[v]) { visited[v] = true; q.push(v); cnt++; } } } return cnt; // excluding s } //A Plug for UNIX int main() { int n,m,mm,i,j,k,r,r2; map<string, int> receptacleMap; string receptacle,plug,device; dinic_init(); cin>>n; mm=100; for(i=1;i<=n;i++) { cin>>receptacle; //receptacleMap[receptacle]=i+m; //这里m还没有值,所以使用mm来代替 receptacleMap[receptacle]=i+mm; } j=mm+n; cin>>m; for(i=1;i<=m;i++) { cin>>device>>plug; r=receptacleMap[plug]; if(r==0) { receptacleMap[plug]=++j; add_edge(j,i,1,0); } else { add_edge(r,i,1,0); } } cin>>k; for(i=1;i<=k;i++) { cin>>receptacle>>plug; r=receptacleMap[receptacle]; if(r==0) { receptacleMap[receptacle]=++j; } r=receptacleMap[plug]; if(r==0) { receptacleMap[plug]=++j; } r=receptacleMap[receptacle]; r2=receptacleMap[plug]; add_edge(r2,r,INT_MAX,0); } for(i=1;i<=m;i++) { add_edge(i,j+1,1,0); } for(i=1;i<=n;i++) { add_edge(0,mm+i,1,0); } cout<<m-dinic(0,j+1)<<endl; return 0; }