poj1459 Power Network (最大流)
多源最大流问题,可以构造成一般最大流问题,增加一个起点和一个终点。起点指向每个Power station,边的权值为Power station的Pmax。每个Consumer指向终点,边的权值为Cmax。Dispatcher看做一般节点。
用EK算法算法实现的版本,Time:766MS
Code
1 #include <iostream>
2 #include <stdio.h>
3 #define SIZE 103
4 using namespace std;
5
6 int n, np, nc, m, source, sink;
7 int map[SIZE][SIZE];
8 //FIFO queue============================================
9 struct QUEUE{
10 int queue[SIZE];
11 int head;
12 int tail;
13 };
14 struct QUEUE q;
15 int color[SIZE], par[SIZE];
16
17 int InitQ(){
18 q.head=q.tail=0;
19 return 1;
20 }
21 int EnQ(int x){
22 q.queue[q.tail]=x;
23 q.tail++;
24 return 1;
25 }
26 int DeQ(){
27 int x;
28 x=q.queue[q.head];
29 q.head++;
30 return x;
31 }
32 //=====================================================
33 int BFSSearchPath()
34 {
35 int i, u, v, flag;
36 flag=0;
37 InitQ();
38 for (i=1;i<=n;i++){
39 color[i]=0;
40 par[i]=-1;
41 }
42 color[source]=1;
43 par[source]=-1;
44 EnQ(source);
45 while (q.head!=q.tail && !flag){
46 u=DeQ();
47 for (v=0;v<=n;v++){
48 if (map[u][v]!=0 && color[v]==0){
49 color[v]=1;
50 par[v]=u;
51 EnQ(v);
52 if (v==sink){//搜索到最短路径时返回
53 flag=1;
54 break;
55 }
56 }
57 }
58 color[u]=2;
59 }
60 return flag;
61 }
62 int Edmonds_Karp()
63 {
64 int max, min, v;
65 max=0;
66 while (BFSSearchPath()){
67 min=1001;
68 v=sink;
69 //求最短路径上的剩余流量
70 while (v!=source){
71 if (map[par[v]][v]<min){
72 min=map[par[v]][v];
73 }
74 v=par[v];
75 }
76 //根据剩余流量求剩余网络
77 v=sink;
78 while (v!=source){
79 map[par[v]][v]-=min;
80 map[v][par[v]]+=min;
81 v=par[v];
82 }
83 max+=min;
84 }
85 return max;
86 }
87 int main()
88 {
89 int i, u, v, w, Con;
90 char c;
91 //freopen("input.txt", "r", stdin);
92 source=0;
93 while (cin>>n>>np>>nc>>m){
94 memset(map, 0, sizeof(map));
95 for (i=0;i<m;i++){
96 while (c=getchar()!='(');
97 cin>>u;
98 getchar();
99 cin>>v;
100 getchar();
101 cin>>w;
102 map[u+1][v+1]=w;//node's index start from 1
103 }
104 sink=n+1;
105 n+=2; //add the source and sink
106 m+=(np+nc); //add new edges
107 for (i=0;i<np;i++){
108 while (c=getchar()!='(');
109 cin>>u;
110 getchar();
111 cin>>w;
112 map[source][u+1]=w;
113 }
114 for (i=0;i<nc;i++){
115 while (c=getchar()!='(');
116 cin>>u;
117 getchar();
118 cin>>w;
119 map[u+1][sink]=w;
120 }
121 Con=Edmonds_Karp();
122 cout<<Con<<endl;
123 }
124 return 0;
125 }
126
1 #include <iostream>
2 #include <stdio.h>
3 #define SIZE 103
4 using namespace std;
5
6 int n, np, nc, m, source, sink;
7 int map[SIZE][SIZE];
8 //FIFO queue============================================
9 struct QUEUE{
10 int queue[SIZE];
11 int head;
12 int tail;
13 };
14 struct QUEUE q;
15 int color[SIZE], par[SIZE];
16
17 int InitQ(){
18 q.head=q.tail=0;
19 return 1;
20 }
21 int EnQ(int x){
22 q.queue[q.tail]=x;
23 q.tail++;
24 return 1;
25 }
26 int DeQ(){
27 int x;
28 x=q.queue[q.head];
29 q.head++;
30 return x;
31 }
32 //=====================================================
33 int BFSSearchPath()
34 {
35 int i, u, v, flag;
36 flag=0;
37 InitQ();
38 for (i=1;i<=n;i++){
39 color[i]=0;
40 par[i]=-1;
41 }
42 color[source]=1;
43 par[source]=-1;
44 EnQ(source);
45 while (q.head!=q.tail && !flag){
46 u=DeQ();
47 for (v=0;v<=n;v++){
48 if (map[u][v]!=0 && color[v]==0){
49 color[v]=1;
50 par[v]=u;
51 EnQ(v);
52 if (v==sink){//搜索到最短路径时返回
53 flag=1;
54 break;
55 }
56 }
57 }
58 color[u]=2;
59 }
60 return flag;
61 }
62 int Edmonds_Karp()
63 {
64 int max, min, v;
65 max=0;
66 while (BFSSearchPath()){
67 min=1001;
68 v=sink;
69 //求最短路径上的剩余流量
70 while (v!=source){
71 if (map[par[v]][v]<min){
72 min=map[par[v]][v];
73 }
74 v=par[v];
75 }
76 //根据剩余流量求剩余网络
77 v=sink;
78 while (v!=source){
79 map[par[v]][v]-=min;
80 map[v][par[v]]+=min;
81 v=par[v];
82 }
83 max+=min;
84 }
85 return max;
86 }
87 int main()
88 {
89 int i, u, v, w, Con;
90 char c;
91 //freopen("input.txt", "r", stdin);
92 source=0;
93 while (cin>>n>>np>>nc>>m){
94 memset(map, 0, sizeof(map));
95 for (i=0;i<m;i++){
96 while (c=getchar()!='(');
97 cin>>u;
98 getchar();
99 cin>>v;
100 getchar();
101 cin>>w;
102 map[u+1][v+1]=w;//node's index start from 1
103 }
104 sink=n+1;
105 n+=2; //add the source and sink
106 m+=(np+nc); //add new edges
107 for (i=0;i<np;i++){
108 while (c=getchar()!='(');
109 cin>>u;
110 getchar();
111 cin>>w;
112 map[source][u+1]=w;
113 }
114 for (i=0;i<nc;i++){
115 while (c=getchar()!='(');
116 cin>>u;
117 getchar();
118 cin>>w;
119 map[u+1][sink]=w;
120 }
121 Con=Edmonds_Karp();
122 cout<<Con<<endl;
123 }
124 return 0;
125 }
126
又用Dinic算法实现了一次,Time:438MS ,时间果然有很大提高
Code
1 //AC T:438MS
2 #include <iostream>
3 #include <list>
4 #define GSIZE 103
5 #define INF 10000000
6 using namespace std;
7 int src, sink, n, np, nc, m;
8 int map[GSIZE][GSIZE], level[GSIZE], color[GSIZE];
9 int OutDegree(int x)
10 {
11 int i;
12 for (i=0;i<=n;i++){
13 if (map[x][i]!=0 && level[x]+1==level[i])
14 return i;
15 }
16 return 0;
17 }
18 int BFS()//compute a new level graph from the residual graph
19 {
20 int i, u, v, flag;
21 list<int> l;//queue
22 flag=0;
23 for (i=1;i<=n;i++){//necessary?
24 level[i]=INF;
25 color[i]=0;
26 }
27 color[src]=1;
28 l.push_back(src);
29 while(!l.empty()){
30 u=l.front();
31 l.pop_front();
32 for (v=0;v<=n;v++){
33 if (map[u][v]!=0 && color[v]==0){
34 color[v]=1;
35 level[v]=level[u]+1;
36 l.push_back(v);
37 }
38 }
39 if (u==sink)
40 flag=1;
41 color[u]=2;
42 }
43 return flag;
44 }
45 int Dinic()
46 {
47 int maxflow, u, v, resflow, last;
48 list<int> path;//stack
49 list<int>::iterator it;
50 maxflow=0;
51 while(BFS()){
52 path.clear();
53 path.push_back(src);
54 while (OutDegree(src)>0){
55 u=path.back();
56 //search the path from s to t in level graph
57 if (u!=sink){
58 if ((v=OutDegree(u))!=0)
59 path.push_back(v);
60 else{
61 path.pop_back();
62 level[u]=INF;
63 }
64 }
65 //update the residual graph along path
66 else{
67 resflow=INF;
68 for (it=path.begin();it!=path.end();it++){
69 u=*it;
70 if ((++it)==path.end())
71 break;
72 v=*it;
73 if (map[u][v]<resflow)
74 resflow=map[u][v];
75 --it;
76 }
77 last=-1;
78 maxflow+=resflow;
79 for (it=path.begin();it!=path.end();it++){
80 u=*it;
81 if ((++it)==path.end())
82 break;
83 v=*it;
84 map[u][v]-=resflow;
85 map[v][u]+=resflow;
86 if (map[u][v]==0 && last==-1)//label the last vertex reachable from s
87 last=u;
88 --it;
89 }
90 while (path.back()!=last)
91 path.pop_back();
92 }
93 }
94 }
95 return maxflow;
96 }
97 int main(int argc, char *argv[])
98 {
99 int i, u, v, w, Con;
100 char c;
101 //freopen("input.txt", "r", stdin);
102 src=0;
103 while (cin>>n>>np>>nc>>m){
104 memset(map, 0, sizeof(map));
105 for (i=0;i<m;i++){
106 while (c=getchar()!='(');
107 cin>>u;
108 getchar();
109 cin>>v;
110 getchar();
111 cin>>w;
112 map[u+1][v+1]=w;
113 }
114 sink=n+1;
115 n+=2; //add the src and sink
116 m+=(np+nc); //add new edges
117 for (i=0;i<np;i++){
118 while (c=getchar()!='(');
119 cin>>u;
120 getchar();
121 cin>>w;
122 map[src][u+1]=w;
123 }
124 for (i=0;i<nc;i++){
125 while (c=getchar()!='(');
126 cin>>u;
127 getchar();
128 cin>>w;
129 map[u+1][sink]=w;
130 }
131 Con=Dinic();
132 cout<<Con<<endl;
133 }
134 return 0;
135 }
1 //AC T:438MS
2 #include <iostream>
3 #include <list>
4 #define GSIZE 103
5 #define INF 10000000
6 using namespace std;
7 int src, sink, n, np, nc, m;
8 int map[GSIZE][GSIZE], level[GSIZE], color[GSIZE];
9 int OutDegree(int x)
10 {
11 int i;
12 for (i=0;i<=n;i++){
13 if (map[x][i]!=0 && level[x]+1==level[i])
14 return i;
15 }
16 return 0;
17 }
18 int BFS()//compute a new level graph from the residual graph
19 {
20 int i, u, v, flag;
21 list<int> l;//queue
22 flag=0;
23 for (i=1;i<=n;i++){//necessary?
24 level[i]=INF;
25 color[i]=0;
26 }
27 color[src]=1;
28 l.push_back(src);
29 while(!l.empty()){
30 u=l.front();
31 l.pop_front();
32 for (v=0;v<=n;v++){
33 if (map[u][v]!=0 && color[v]==0){
34 color[v]=1;
35 level[v]=level[u]+1;
36 l.push_back(v);
37 }
38 }
39 if (u==sink)
40 flag=1;
41 color[u]=2;
42 }
43 return flag;
44 }
45 int Dinic()
46 {
47 int maxflow, u, v, resflow, last;
48 list<int> path;//stack
49 list<int>::iterator it;
50 maxflow=0;
51 while(BFS()){
52 path.clear();
53 path.push_back(src);
54 while (OutDegree(src)>0){
55 u=path.back();
56 //search the path from s to t in level graph
57 if (u!=sink){
58 if ((v=OutDegree(u))!=0)
59 path.push_back(v);
60 else{
61 path.pop_back();
62 level[u]=INF;
63 }
64 }
65 //update the residual graph along path
66 else{
67 resflow=INF;
68 for (it=path.begin();it!=path.end();it++){
69 u=*it;
70 if ((++it)==path.end())
71 break;
72 v=*it;
73 if (map[u][v]<resflow)
74 resflow=map[u][v];
75 --it;
76 }
77 last=-1;
78 maxflow+=resflow;
79 for (it=path.begin();it!=path.end();it++){
80 u=*it;
81 if ((++it)==path.end())
82 break;
83 v=*it;
84 map[u][v]-=resflow;
85 map[v][u]+=resflow;
86 if (map[u][v]==0 && last==-1)//label the last vertex reachable from s
87 last=u;
88 --it;
89 }
90 while (path.back()!=last)
91 path.pop_back();
92 }
93 }
94 }
95 return maxflow;
96 }
97 int main(int argc, char *argv[])
98 {
99 int i, u, v, w, Con;
100 char c;
101 //freopen("input.txt", "r", stdin);
102 src=0;
103 while (cin>>n>>np>>nc>>m){
104 memset(map, 0, sizeof(map));
105 for (i=0;i<m;i++){
106 while (c=getchar()!='(');
107 cin>>u;
108 getchar();
109 cin>>v;
110 getchar();
111 cin>>w;
112 map[u+1][v+1]=w;
113 }
114 sink=n+1;
115 n+=2; //add the src and sink
116 m+=(np+nc); //add new edges
117 for (i=0;i<np;i++){
118 while (c=getchar()!='(');
119 cin>>u;
120 getchar();
121 cin>>w;
122 map[src][u+1]=w;
123 }
124 for (i=0;i<nc;i++){
125 while (c=getchar()!='(');
126 cin>>u;
127 getchar();
128 cin>>w;
129 map[u+1][sink]=w;
130 }
131 Con=Dinic();
132 cout<<Con<<endl;
133 }
134 return 0;
135 }
END