hdu 4289 Control (最大流 最小割 成都赛区 网络赛)

http://acm.hdu.edu.cn/showproblem.php?pid=4289


题意: 有n个城市,有个小偷想从其中一个城市逃到另一个城市,警察想要堵截这个小偷,知道了在每个城市堵截的成本,问如何安排在哪些城市堵截可以使得

          小偷一定会被抓住,而且成本最低。

题解 : 最大流 ; 将每一个点 查分成两个  ,x 和x+n  他们之间的流量为 在 x 点的花费  ,对于 右边相连的x,y   l连接 x +n  到 y 和 y +n到  x   流量值 为 inf ,(这样保证了  流量 只受拆点边的限制)  最后 求  s  到  e+n 的 最值 即可

dinic  算法:

  1 #include<cstdio>
  2  #include<cstring>
  3  #include<cmath>
  4  #include<iostream>
  5  #include<algorithm>
  6  #include<set>
  7  #include<map>
  8  #include<queue>
  9  #include<vector>
 10  #include<string>
 11 #define INF 0x7fffffff
 12 #define F(x) (x)
 13 #define N(x) (205+(x))
 14 #define CPN(x) (410+(x))
 15 #define D(x) (615+(x))
 16 #define maxn 420
 17 #define CL(a,b) memset(a,b,sizeof(a))
 18 
 19 using namespace std;
 20 
 21  int next[maxn],dis[maxn];
 22  int s,e;
 23  int  n, m,cnt,a[maxn];
 24  struct node
 25  {
 26      int to;
 27      int cap ;
 28      int next ;
 29  }p[200000] ;
 30  void add(int x,int y,int cap)
 31  {
 32      p[cnt].to = y;
 33      p[cnt].cap = cap ;
 34      p[cnt].next = next[x];
 35      next[x] = cnt++ ;
 36 
 37      p[cnt].to = x;
 38      p[cnt].cap = 0;
 39      p[cnt].next = next[y];
 40      next[y] = cnt++ ;
 41  }
 42  int bfs()// 重新 建 图 (按 层数 建图)
 43  {
 44 
 45      memset(dis,-1,sizeof(dis)) ;
 46      dis[s] = 0 ;
 47      queue<int>que;
 48      que.push(s);
 49 
 50      while(!que.empty())
 51      {
 52 
 53 
 54          int  k = que.front();que.pop() ;
 55          forint i = next[k];i!=-1;i = p[i].next)
 56          {
 57              int v = p[i].to;
 58 
 59 
 60              int cap = p[i].cap ;
 61 
 62              if(cap > 0 && dis[v] < 0 )// 如果 可以  可以到达 但 还没有 访问
 63              {
 64 
 65                  dis[v] = dis[k]+ 1 ;
 66                  que.push(v) ;
 67              }
 68          }
 69 
 70      }
 71 
 72 
 73      if(dis[e] > 0return 1;
 74      else return  0 ;
 75 
 76  }
 77 
 78 
 79 
 80  int  dfs(int x,int mx)// 查找  路径上的 最小 的 流量
 81  {
 82 
 83      int i , a ,tf =  0;
 84 
 85      if(x == e) return mx ;
 86 
 87      for(i = next[x];i!= - 1;i = p[i].next)
 88      {
 89          int v = p[i].to ;
 90          int cap = p[i].cap ;
 91          if(cap > 0 && dis[v] == dis[x] + 1  && (a =dfs(v,min(cap,mx))))
 92          {
 93 
 94              p[i].cap -= a;
 95              p[i^1].cap += a;
 96 
 97                return a;
 98 
 99 
100          }
101      }
102      if(!tf) dis[x] = -1;// 没有 找到 最小流量 ,说明 从这个点到不了 终点 ,所以  标记一下
103      return tf ;
104  }
105 
106 
107 
108 
109 
110  int main()
111  {
112     int i , j ,x,y;
113     int a;
114      //freopen("data.txt","r",stdin) ;
115     while(scanf("%d%d%d%d",&n,&m,&s,&e)!=EOF)
116     {
117 
118         CL(next,-1) ;
119         cnt = 0;
120        // scanf("%d%d",&s,&e);
121         for(i = 1 ; i <= n;i++)
122         {
123              scanf("%d",&a) ;
124               add(i,i+n,a);
125         }
126 
127 
128          for(i = 0 ;i< m;i++)
129          {
130              scanf("%d%d",&x,&y);
131 
132              add(x+n,y,INF) ;
133              add(y + n ,x,INF) ;
134          }
135 
136         e = e + n;
137 
138 
139        int ans = 0;
140        int res;
141 
142        while(bfs())
143        {
144 
145 
146           while(res = dfs(s,INF)) ans+= res ;
147 
148        }
149        printf("%d\n",ans);
150     }
151  }

 isap 算法:

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<cmath>
  4 #include<iostream>
  5 #include<algorithm>
  6 #include<set>
  7 #include<map>
  8 #include<queue>
  9 #include<vector>
 10 #include<string>
 11 #define INF 0x7fffffff
 12 #define maxn 500
 13 #define CL(a,b) memset(a,b,sizeof(a))
 14 
 15 using namespace std;
 16 struct node
 17 {
 18     int to;
 19     int cap;
 20     int  next;
 21 }p[200000] ;
 22 int dis[maxn],gap[maxn] ,cnt,next[maxn],s,e;
 23 int  n , m,NN ;//NN 为  加完点 之后的 总结点数
 24 void add(int from,int to,int cap)//加 的 是 有向边 
 25 {
 26     p[cnt].to = to;
 27     p[cnt].cap = cap ;
 28     p[cnt].next = next[from];
 29     next[from] = cnt++;
 30 
 31     p[cnt].to = from;
 32     p[cnt].cap = 0;
 33     p[cnt].next = next[to];
 34     next[to] = cnt++ ;
 35 }
 36 int dfs(int pos,int cost)
 37 {
 38 
 39     if(pos == e)
 40      return cost ;
 41 
 42     int i,j ,mdis = NN ,f = cost ;
 43 
 44     for(i =  next[pos];i != - 1; i = p[i].next)
 45     {
 46         int to = p[i].to ;
 47         int cap = p[i].cap ;
 48         if(cap > 0 )
 49         {
 50             if(dis[to] + 1 == dis[pos])
 51             {
 52 
 53 
 54               int d = min(f,cap) ;// 注意 这 为 剩余 流量 和 cap 的 最小值
 55 
 56               d = dfs(to,d) ;
 57               p[i].cap -=d;
 58               p[i^1].cap +=d;
 59               f -= d;
 60 
 61               if(dis[s] >= NN)  return cost - f;// 如果没有 了 增广路经 结束算法
 62               if(f == 0break ;
 63             }
 64             if( dis[to] < mdis ) mdis = dis[to] ;// 记录可扩展的最小的狐
 65 
 66         }
 67 
 68     }
 69     if(f == cost)//  没有 可以 扩展的点
 70     {
 71         --gap[dis[pos]];
 72         if(gap[dis[pos]] == 0)dis[s] = NN;// 注意这 ,若 距离 为 dis[pos] 这一层都没有 扩展点了(断层) dis[s] = n
 73 
 74         dis[pos] = mdis + 1;
 75 
 76         ++gap[dis[pos]] ;
 77     }
 78     return cost  - f ;
 79 }
 80 int isap( int b,int t)
 81 {
 82 
 83     int ret =  0;
 84     s = b;
 85     e = t;
 86     CL(gap,0);
 87     CL(dis,0) ;
 88     gap[0] = NN ;
 89     while(dis[s] < NN)
 90     {
 91         ret+=dfs(s,INF) ;
 92     }
 93     return ret ;
 94 
 95 }
 96 int main()
 97 {
 98     int  i,x,y,a,b,t;
 99     //freopen("data.txt","r",stdin) ;
100     while(scanf("%d%d%d%d",&n,&m,&b,&t)!=EOF)
101     {
102         CL(next,-1);
103         cnt = 0 ;
104         NN = 2*n  ;//NN 为  加完点 之后的 总结点数
105         for(i = 1;i <=n;i++)
106         {
107             scanf("%d",&a);
108             add(i,i+n,a) ;
109         }
110         for(i = 0; i<m;i++)
111         {
112             scanf("%d%d",&x,&y);
113             add(x+n,y,INF);
114             add(y + n,x,INF);
115         }
116 
117         int ans = isap(b,t + n) ;
118         printf("%d\n",ans) ;
119     }
120 }

 

 

posted @ 2012-09-21 22:11  Szz  阅读(461)  评论(1编辑  收藏  举报