zoukankan      html  css  js  c++  java
  • POJ 1459 构图+最大流(Edmond_karp模版)

    题目链接: http://poj.org/problem?id=1459

    题目大意:

      给定一个有向图,n个点,m条边( 1<=n<=100, m<=n^2 ),点有三类: np个 power station,nc个consumer,其余的是普通的点,其中np个power station可以产生power供给网络传递,nc个consumer消耗能量,每个power station有一个最大的供应值value,每个consumer有一个最大的消耗值value,问最终可以消耗能量的最大值;

    分析:

      我的构图方式: 虚拟一个源点S(S=0),其余输入的点都+1,虚拟一个汇点T(T=n+1),S向所有的power station引一条边,边权(容量)为相应的power station的value值,所有的consumer向T引一天边,边权(容量)为相应consumer的value值;

      之后用Edmond_karp模版求最大流即可;

    注意:

      我开始想用%*来处理一些多余的空格,回车的输入,后来失败了,后来读入m个串,np个串,nc个串来解决问题(下面的代码就是这样),然后又看了大众的代码,发现都是这样输入的:

    scanf(" (%d,%d)%d", ...); // 即括号前面加了空格;

    scanf(" (%d)%d", ...);

    代码:

    poj1459
      1 /*1459    Accepted    212K    375MS    C++    2908B    2012-04-23 19:59:30*/
      2 #include <cstdio>
      3 #include <cstring>
      4 #include <cmath>
      5 #include <iostream>
      6 #include <algorithm>
      7 #include <vector>
      8 using namespace std;
      9 
     10 #define mpair make_pair
     11 #define pii pair<int,int>
     12 #define MM(a,b) memset(a,b,sizeof(a));
     13 typedef long long lld;
     14 typedef unsigned long long u64;
     15 template<class T> bool up_max(T& a,const T& b){return b>a? a=b,1 : 0;}
     16 template<class T> bool up_min(T& a,const T& b){return b<a? a=b,1 : 0;}
     17 #define maxn 110
     18 #define inf 2100000000
     19 int n, np, nc, m, S, T;
     20 int mark[maxn]; // 0: station;  1: consumer; 2: anthter;
     21 // all station should be linked to the sourse; and all consumer should be linked to the sink;
     22 int g[maxn][maxn];
     23 void Read(){
     24     int i,j,u,v,w;
     25     char ch[100];
     26     for(i=0;i<=n+1;++i)
     27         for(j=0;j<=n+1;++j)
     28             g[i][j]= 0;
     29 
     30     for(i=1;i<=m;++i){
     31         //scanf( "%*[ ]%*['\n'](%d,%d)%d", &u, &v, &w );
     32         //scanf( "%*[ ](%d,%d)%d", &u, &v, &w );
     33         scanf("%s", ch);
     34         u= 0;
     35         for(j=1;ch[j]!=',';++j)
     36             u= u*10 + ch[j]-'0';
     37         v= 0;
     38         for(++j;ch[j]!=')';++j)
     39             v= v*10 + ch[j]-'0';
     40         w= 0;
     41         for(++j;ch[j];++j)
     42             w= w*10 + ch[j]-'0';
     43         ++u, ++v;
     44         g[u][v]= w;
     45     }
     46 
     47 
     48     for(i=1;i<=np;++i){
     49         //scanf("%*[ ](%d)%d", &u, &w);
     50         //scanf("%*[ ]%*['\n'](%d)%d", &u, &w);
     51         scanf("%s", ch);
     52         u= 0;
     53         for(j=1;ch[j]!=')';++j)
     54             u= u*10 + ch[j]-'0';
     55         w= 0;
     56         for(++j;ch[j];++j)
     57             w= w*10 + ch[j]-'0';
     58         ++u;
     59         g[0][u]= w;
     60     }
     61     for(i=1;i<=nc;++i){
     62         //scanf("%*[ ](%d)%d", &u, &w);
     63         //scanf("%*[ ]%*['\n'](%d)%d", &u, &w);
     64         scanf("%s", ch);
     65         u= 0;
     66         for(j=1;ch[j]!=')';++j)
     67             u= u*10 + ch[j]-'0';
     68         w= 0;
     69         for(++j;ch[j];++j)
     70             w= w*10 + ch[j]-'0';
     71         ++u;
     72         g[u][T]= w;
     73     }
     74 }
     75 
     76 int pre[maxn];
     77 int que[maxn];
     78 bool vis[maxn];
     79 bool bfs(){
     80     MM( vis, 0 );
     81     int head= 0, tail= 0;
     82     que[tail++]= S;
     83     vis[S]= 1;
     84     while(head<tail){
     85         int u= que[head++];
     86         for(int i=1;i<=T;++i){
     87             if( g[u][i] && !vis[i] ){
     88                 vis[i]= 1;
     89                 pre[i]= u;
     90                 if(i==T) return 1;
     91                 que[tail++]= i;
     92             }
     93         }
     94     }
     95     return 0;
     96 }
     97 int Edmond_karp(){
     98     int i,ans= 0;
     99     while( bfs() ){
    100         int t= inf;
    101         for(i= T; i!= S; i= pre[i])
    102             up_min( t, g[pre[i]][i] );
    103         ans+= t;
    104         for(i=T; i!=S; i= pre[i]){
    105             g[pre[i]][i]-= t;
    106             g[i][pre[i]]+= t;
    107         }
    108     }
    109     return ans;
    110 }
    111 
    112 int main()
    113 {
    114     while( scanf("%d%d%d%d", &n, &np, &nc, &m) != EOF ){
    115         S= 0, T= n+1;
    116         Read();
    117         printf("%d\n", Edmond_karp() );
    118     }
    119 }
    一毛原创作品,转载请注明出处。
  • 相关阅读:
    收藏网站制作常用经典css.div.布局.设计实例打包下载2
    下拉菜单 效果
    鼠标放在一个连接上,会显示图片(类似tooltip)
    收藏网站制作常用经典ajax.prototype.javascript实例打包下载2
    开发速查手册
    Visual Studio 2005 的 101 个示例(转)
    多行文本框限制输入字符长度(跳出窗体提示)
    发一个不用图片实现圆角代码,非常经典
    收藏网站制作常用经典css.div.布局.设计实例打包下载1
    Linux下php动态添加扩展
  • 原文地址:https://www.cnblogs.com/yimao/p/2467054.html
Copyright © 2011-2022 走看看