pku 1459 最大流

    个人认为网络流问题是图论里比较简单的东西!

    前几天做了pku 1459,用的比较简单的sap,比较郁闷的是无论如何优化时间老是在1000左右转,后来用dinic,几乎同样的代码,用时差不多是别人的十倍,后来想一下,或许,是stl 的问题。。。

    今天验证了一下,不错,就是它的原因,因为sap用广搜来找最短增广路,所以用到了队列,但是队列元素很少,一般的网络流节点个数都是三位数量级的,所以,在一次又一次的用队列时浪费了大量时间,由于数据量很小,手工模拟了一下,时间下降了五倍。。。

    200左右,虽说还是很大,总算可以接受了!

    1459算是网络流的入门题,一个电力网络,各种各样的节点加上电路,赤裸裸的最大流,额。。。

是无源无汇的网络最大流,这样的最大流就应该给他改一下,因为图中有好多源点,所以加一个强制源点,到各个源点的权值就是源点的值,然后加一个汇点,所有汇点都汇总到这儿,然后求强制源点到最终汇点的最大流就行了!

代码
   
     
1 #include < string .h >
2 #include < stdio.h >
3 #include < queue >
4 #include < iostream >
5   using namespace std;
6   int cost[ 105 ][ 105 ],n,m,np,nc,r,pos;
7 int Min[ 105 ],pre[ 105 ];
8 bool visit[ 105 ];
9 int bfs()
10 {
11 int q[ 105 ],start = 0 ,end = 0 ;
12 memset(visit, false , sizeof (visit));
13 q[ 0 ] = n;
14 visit[n] = true ;
15 Min[n] = 0x7fffffff ;
16 while (start <= end)
17 {
18 int t = q[start];
19 for ( int i = 0 ; i <= n + 1 ; i ++ )
20 if ( ! visit[i] && cost[t][i] != 0 )
21 {
22 Min[i] = (Min[t] < cost[t][i]) ? Min[t] : cost[t][i];
23 pre[i] = t;
24 if (i == n + 1 )
25 return Min[n + 1 ];
26 visit[i] = true ;
27 q[ ++ end] = i;
28 }
29 start ++ ;
30 }
31 if (visit[n + 1 ])
32 return Min[n + 1 ];
33 else return - 1 ;
34 }
35 void Ford_Fulkerson()
36 {
37 int max = 0 ,t,pre_t;
38 while ((r = bfs()) != - 1 )
39 {
40 max += r;
41 t = n + 1 ;
42 while (t != n)
43 {
44 pre_t = pre[t];
45 cost[pre_t][t] -= r;
46 cost[t][pre_t] += r;
47 t = pre_t;
48 }
49 }
50 printf ( " %d\n " ,max);
51 }
52 int main()
53 {
54 int i,k,x,y;
55 while (scanf ( " %d%d%d%d " , & n, & np, & nc, & m) != EOF)
56 {
57 memset(cost, 0 , sizeof (cost));
58 for (i = 0 ; i < m; i ++ )
59 {
60 scanf ( " (%d,%d)%d " , & x, & y, & k);
61 cost[x][y] += k;
62 }
63 for (i = 0 ; i < np; i ++ )
64 {
65 scanf ( " (%d)%d " , & x, & k);
66 cost[n][x] = k;
67 }
68 for (i = 0 ; i < nc; i ++ )
69 {
70 scanf ( " (%d)%d " , & x, & k);
71 cost[x][n + 1 ] = k;
72 }
73 Ford_Fulkerson();
74 }
75 return 0 ;
76 }
77
78

 

你可能感兴趣的:(pku)