POJ 1087 ZOJ 1157 插头和插座 网络流 繁琐 不喜欢
2013-04-27 20:09
363 查看
这个题的做法我已经知道,就是先构造出图,用网络流算法走个最大流,由于只有插头插座两种,也可以用二分图(二部图)匹配,但是要我写代码,感觉很烦躁,拖了很久,终于用网络流A了它。
记录第一次用map,呵呵。因为老是要做查找操作,所以试试map,希望能省点时间。
构图方式如下:
加入超源点s和超收点t
s点到所有插座的容量为1(因为该插座只有一个)
设备要用的插头到t点的容量为该类型插头的个数(例如有3个设备是B插头,插头B到t的容量为3)
插头能直接插在插座上(名字相同),那么插座到插头的容量为无穷。
插头能通过交换器连接到插座上,该插座到插头的容量也为无穷,用最大流算法求出能输送多少到超收点。
再用设备数-该值即为所求。
先贴POJ上能过的较繁琐,但是可能更直观的代码:
View Code
代码的长度也有所减少啊
记录第一次用map,呵呵。因为老是要做查找操作,所以试试map,希望能省点时间。
构图方式如下:
加入超源点s和超收点t
s点到所有插座的容量为1(因为该插座只有一个)
设备要用的插头到t点的容量为该类型插头的个数(例如有3个设备是B插头,插头B到t的容量为3)
插头能直接插在插座上(名字相同),那么插座到插头的容量为无穷。
插头能通过交换器连接到插座上,该插座到插头的容量也为无穷,用最大流算法求出能输送多少到超收点。
再用设备数-该值即为所求。
先贴POJ上能过的较繁琐,但是可能更直观的代码:
View Code
#include <cstdio> #include <iostream> #include <cstring> #include <string> #include <map> #include <queue> using namespace std; #define MAXN 400 #define INF 0x7fffffff #define min(a,b) a<b?a:b map<string,int>mp;//原插座转换器 map<string,int>dev; bool edge[MAXN][MAXN];//原插座+转换器的邻接矩阵 int ss,tt;//源点和汇点 int n,m; int cur,ser;//原插座+设备的数目 int resi[MAXN][MAXN]; //容量网络 char a[MAXN][30];//存转换器中的插头插座名字 void init1()//读入会议室提供的插座和设备所需插座 { int i; map<string,int>::iterator it; memset(resi,0,sizeof(resi)); scanf("%d",&n); for(i=0; i<n; ++i) { cin>>a[i]; mp[a[i]] = i; } ss = n; tt = n+1; scanf("%d",&m); cur = n+1; for(i=0; i<m; ++i) { string d,dname; cin>>dname>>d; it = dev.find(d); if(it != dev.end()) ++resi[(*it).second][tt]; else { dev[d] = ++cur; resi[cur][tt] = 1; } } for(int i=0; i<n; ++i) { resi[ss][i] = 1; string s = a[i]; it = dev.find(s); if(it != dev.end()) resi[i][(*it).second] = INF; } } void init2()//读入转换器的情况,构造出转换的邻接矩阵 { int k; map<string,int>::iterator it1,it2; scanf("%d",&k); memset(edge,0,sizeof(edge)); ser = n-1; while(k--) { string s1,s2; cin>>s2>>s1; int id1,id2; it1 = mp.find(s1); if(it1 == mp.end()) { mp[s1] = ++ser; strcpy(a[ser],s1.c_str()); id1 = ser; } else id1 = (*it1).second; it2 = mp.find(s2); if(it2 == mp.end()) { mp[s2] = ++ser; strcpy(a[ser],s2.c_str()); id2 = ser; } else id2 = (*it2).second; edge[id1][id2] = 1; } } void init3()//如果v设备插的插座可以由u转来,那么resi[u][v] = INF { queue<int>Q; map<string,int>::iterator it; for(int i=0; i<n; ++i) { Q.push(i); while(!Q.empty()) { int u = Q.front(); Q.pop(); for(int j=0; j<=ser; ++j) { if(edge[u][j] == 1) { Q.push(j); string s = a[j]; it = dev.find(s); if(it != dev.end()) resi[i][(*it).second] = INF; } } } } } void pushRelabel() { queue<int>act; int ef[MAXN],h[MAXN]; int i; int sum = 0; int u,p; memset(ef,0,sizeof(ef)); memset(h,0,sizeof(h)); h[ss] = cur+1; ef[ss] = INF; ef[tt] = -INF; act.push(ss); while(!act.empty()) { u =act.front(); act.pop(); for(i=0; i<=cur; ++i) { p = min(resi[u][i],ef[u]); if(p>0 &&(u == ss || h[u] == h[i]+1)) { resi[u][i] -= p; resi[i][u] += p; ef[u] -= p; ef[i] += p; if(i == tt) sum += p; if(i != ss && i != tt) act.push(i); } } if(u != ss && u != tt && ef[u] >0) { ++h[u]; act.push(u); } } printf("%d\n",m-sum); } int main() { // freopen("in.cpp","r",stdin); int T; scanf("%d",&T); while(T--) { mp.clear(); dev.clear(); init1(); init2(); init3(); pushRelabel(); if(T != 0) puts(""); } return 0; }
代码的长度也有所减少啊
相关文章推荐
- POJ 1087 A Plug for UNIX / HDU 1526 A Plug for UNIX / ZOJ 1157 A Plug for UNIX / UVA 753 A Plug for UNIX / UVAlive 5418 A Plug for UNIX / SCU 1671 A Plug for UNIX (网络流)
- zoj 1157 || poj 1087 A Plug for UNIX
- ZOJ 1157 A Plug for UNIX (POJ 1087)
- POJ 1087 A Plug for UNIX 会议室插座问题 构图+最大流
- POJ 1087 网络流 最大流
- poj 1087 A Plug for UNIX(网络流最大流)
- POJ 1087 网络流(最大流 ISAP)
- poj 1087 A Plug for UNIX 【图论-网络流-最大流】
- POJ 1087 A Plug for UNIX(网络流)
- 网络流 ( ISAP+建图 )——A Plug for UNIX ( POJ 1087 )
- poj 1087 C - A Plug for UNIX 网络流最大流
- poj1087——A Plug for UNIX(网络流,超级源点、汇点)
- POJ-1087 A Plug for UNIX 网络流
- POJ 1087 A Plug for UNIX(网络流—最大流(最大二分匹配))
- POJ 1459 ZOJ 1734 Power Network dinic 算法 网络流
- POJ1087 A Plug for UNIX(网络流,最大流,EK算法)
- 网络流之顶点连通度 poj 1966 zoj 2182
- poj 3204 Ikki's Story I - Road Reconstruction && zoj 2532 Internship 网络流关键边
- poj 3204 Ikki's Story I - Road Reconstruction && zoj 2532 Internship 网络流关键边
- POJ 1459 Power Network / HIT 1228 Power Network / UVAlive 2760 Power Network / ZOJ 1734 Power Network / FZU 1161 (网络流,最大流)