zoukankan      html  css  js  c++  java
  • POJ 1459 ZOJ 1734 Power Network dinic 算法 网络流

    裸的网络流,就是在读数据的时候,注意用while(getchar()!='(');scanf("%d,%d),%d");

    然后增加超源点与超收点。我是用dinic算法,速度慢,跑了549貌似ms,貌似,希望能优化,用个什么预流推进算法试试啊。

    在纠结了很久后,终于在书上把预流推进算法抄下来了,哈哈,调试了很久,一直陷入死循环,后来一看输入文件不是这个题的输入,想shi啊,有木有

    贴代码  dinic 算法 :

    View Code
     1 #include <cstdio>
     2 #include <cstring>
     3 #define MAXN 108
     4 #define INF 300000000
     5 int n,np,nc,m;
     6 int s ;//源点
     7 int t; //汇点
     8 int map[MAXN][MAXN];//容量网络
     9 bool sign[MAXN][MAXN];//层次网络
    10 void init()
    11 {
    12     int i;
    13     int u,v,z;
    14     s = n;
    15     t = n+1;
    16     memset(map,0,sizeof(map));
    17     for(i=0; i<m; ++i)
    18     {
    19         while(getchar() != '(');
    20         scanf("%d,%d)%d",&u,&v,&z);
    21         map[u][v] = z;
    22     }
    23     for(i=0; i<np; ++i)
    24     {
    25         while(getchar() != '(');
    26         scanf("%d)%d",&u,&z);
    27         map[s][u] = z;
    28     }
    29     for(i =0; i<nc; ++i)
    30     {
    31         while(getchar() != '(');
    32         scanf("%d)%d",&u,&z);
    33         map[u][t] = z;
    34     }
    35 }
    36 int min(int x,int y)
    37 {
    38     return x<y ? x : y;
    39 }
    40 bool BFS()
    41 {
    42     bool used[MAXN];
    43     int queue[MAXN];
    44     int fr=0,ta=0;
    45     int i;
    46     memset(used,0,sizeof(used));
    47     memset(sign,0,sizeof(sign));
    48     queue[ta++] = s;
    49     used[s] = 1;
    50     while(fr != ta)
    51     {
    52         int v = queue[fr++];
    53         for(i=0; i<=n+1; ++i)
    54         {
    55             if(!used[i] && map[v][i])
    56             {
    57                 queue[ta++] = i;
    58                 sign[v][i] = 1;
    59                 used[i] = 1;
    60             }
    61         }
    62     }
    63     return used[t];
    64 }
    65 int  DFS(int v,int sum)
    66 {
    67     int i,r,f;
    68     if(v == t) return sum;
    69     r = sum;
    70     for(i=0; i<=n+1; ++i)
    71     {
    72         if(sign[v][i])
    73         {
    74             f=DFS(i,min(map[v][i],sum));
    75             map[v][i] -=f;
    76             map[i][v] += f;
    77             sum -= f;
    78         }
    79     }
    80     return r-sum;
    81 }
    82 int main()
    83 {
    84 //    freopen("in.cpp","r",stdin);
    85     while(~scanf("%d%d%d%d",&n,&np,&nc,&m))
    86     {
    87         init();
    88         int ans = 0;
    89         while(BFS()) ans += DFS(s,INF);
    90         printf("%d\n",ans);
    91     }
    92     return 0;
    93 }

    预流推进算法,只跑了150ms,貌似:

    View Code
     1 #include <cstdio>
     2 #include <cstring>
     3 #include <queue>
     4 #define MAXN 110
     5 #define INF 0x7fffffff  //相当于21,4748,3647
     6 using namespace std;
     7 int s,t; //源点和汇点
     8 queue<int> act;
     9 int h[MAXN];  //高度
    10 int ef[MAXN]; //余流,能流出去多少
    11 int n,np,nc,m;
    12 int resi[MAXN][MAXN];//残留网络,每条边的权值表示容量
    13 int min(int x,int y)
    14 {
    15     if(x <y)return x;
    16     else return y;
    17 }
    18 void pushRelabel()
    19 {
    20     int i;
    21     int sum=0;
    22     int u,p;
    23     memset(ef,0,sizeof(ef));
    24     memset(h,0,sizeof(h));
    25     h[s] = n+2;
    26     ef[s] = INF;//源点能往外流正无穷
    27     ef[t] = -INF;//汇点不能往外流,所以汇点能往外流负无穷
    28     act.push(s);
    29     while(!act.empty())
    30     {
    31         u = act.front();
    32         act.pop();
    33         for(i=0; i<=n+1; ++i)
    34         {
    35             p = min(resi[u][i],ef[u]);
    36             if(p > 0 && (u==s || h[u] == h[i]+1))
    37             {
    38                 resi[u][i] -= p;
    39                 resi[i][u] += p;
    40                 ef[u] -= p;
    41                 ef[i] += p;
    42                 if(i == t) sum += p;
    43                 if(i != s && i!=t)
    44                     act.push(i);
    45             }
    46         }
    47         if(u != s && u != t && ef[u] > 0)
    48         {
    49             h[u]++;
    50             act.push(u);
    51         }
    52     }
    53     printf("%d\n",sum);
    54 }
    55 int main()
    56 {
    57 //    freopen("in.cpp","r",stdin);
    58     int i;
    59     int u,v,val;
    60     while(~scanf("%d%d%d%d",&n,&np,&nc,&m))
    61     {
    62         s = n;
    63         t = n+1;
    64         memset(resi,0,sizeof(resi));
    65         for(i=0; i<m; ++i)
    66         {
    67             while(getchar()!='(');
    68             scanf("%d,%d)%d",&u,&v,&val);
    69             resi[u][v] = val;
    70         }
    71         for(i=0; i<np; ++i)
    72         {
    73             while(getchar()!='(');
    74             scanf("%d)%d",&u,&val);
    75             resi[s][u] = val;
    76         }
    77         for(i=0; i<nc; ++i)
    78         {
    79             while(getchar()!='(');
    80             scanf("%d)%d",&u,&val);
    81             resi[u][t] = val;
    82         }
    83         pushRelabel();
    84     }
    85     return 0;
    86 }
  • 相关阅读:
    js动态添加select菜单 联动菜单
    用户控件的缓存技术之一【共三篇】
    删除根节点下的所有子节点
    兼容FF和IE的tooltip 鼠标提示框
    【ABAP系列】SAP ABAP常用正则表达式大全
    【ABAP系列】SAP ABAP中关于commit的一点解释
    【SD系列】SAP SD模块-创建供应商主数据BAPI
    【SQL系列】从SQL语言的分类谈COMMIT和ROLLBACK的用法
    【ABAP系列】SAP ABAP控制单元格是否可编辑
    【ABAP系列】SAP ABAP 关于BAPI的EXTENSIONIN 一点解释
  • 原文地址:https://www.cnblogs.com/allh123/p/3010232.html
Copyright © 2011-2022 走看看