zoukankan      html  css  js  c++  java
  • ZOJ 2364 Data Transmission (最大流:Dinic+贪心预流)

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2364

    裸的最大流。。。

    用了Dinic、ISAP、HLPP都TLE。。。

    然后在网上看到了个贪心预流的优化,就AC了,2030ms

    贪心预流仅用于预处理分层图网络流

    HLPP一般适合处理分层图,但是怎么加了贪心预流还是T了。。DINIC和ISAP加了贪心预流就AC了。。

    同时附上Dinic和贪心预流模板~

      1 //#pragma comment(linker, "/STACK:102400000,102400000")
      2 #include<cstdio>
      3 #include<iostream>
      4 #include<cstring>
      5 #include<string>
      6 #include<cmath>
      7 #include<set>
      8 #include<list>
      9 #include<map>
     10 #include<iterator>
     11 #include<cstdlib>
     12 #include<vector>
     13 #include<queue>
     14 #include<stack>
     15 #include<algorithm>
     16 #include<functional>
     17 using namespace std;
     18 typedef long long LL;
     19 #define ROUND(x) round(x)
     20 #define FLOOR(x) floor(x)
     21 #define CEIL(x) ceil(x)
     22 //const int maxn=0;
     23 //const int inf=0x3f3f3f3f;
     24 const LL inf64=0x3f3f3f3f3f3f3f3fLL;
     25 const double INF=1e30;
     26 const double eps=1e-6;
     27 /**
     28 *最大流最小割:加各种优化的Dinic算法($O(V^2E)$)
     29 *输入:图(链式前向星),n(顶点个数,包含源汇),st(源),ed(汇)
     30 *输出:Dinic(NdFlow)(最大流),MinCut()(最小割)(需先求最大流)
     31 *打印路径方法:按反向边(i&1)的flow 找,或者按边的flow找
     32 */
     33 const int maxn=1510;
     34 const int maxm=600010;
     35 const int inf=0x3f3f3f3f;
     36 struct Edge
     37 {
     38     int u,v;
     39     int cap,flow;
     40     int next;
     41 } edge[maxm];
     42 int head[maxn],edgeNum;//需初始化
     43 int n,m,d[maxn],cur[maxn];
     44 int st,ed;
     45 bool vis[maxn];
     46 void addSubEdge(int u,int v,int cap,int flow)
     47 {
     48     edge[edgeNum].u=u;
     49     edge[edgeNum].v=v;
     50     edge[edgeNum].cap=cap;
     51     edge[edgeNum].flow=flow;
     52     edge[edgeNum].next=head[u];
     53     head[u]=edgeNum++;
     54     cur[u]=head[u];
     55 }
     56 void addEdge(int u,int v,int cap)
     57 {
     58     addSubEdge(u,v,cap,0);
     59     addSubEdge(v,u,0,0);//注意加反向0 边
     60 }
     61 bool BFS()
     62 {
     63     queue<int> Q;
     64     memset(vis, 0, sizeof(vis));
     65     Q.push(st);
     66     d[st]=0;
     67     vis[st]=1;
     68     while (!Q.empty())
     69     {
     70         int u=Q.front();
     71         Q.pop();
     72         for(int i=head[u]; i!=-1; i=edge[i].next)
     73         {
     74             int v=edge[i].v;
     75             int w=edge[i].cap-edge[i].flow;
     76             if(w>0 && !vis[v])
     77             {
     78                 vis[v]=1;
     79                 Q.push(v);
     80                 d[v]=d[u]+1;
     81                 if(v==ed) return 1;
     82             }
     83         }
     84     }
     85     return false;
     86 }
     87 int Aug(int u, int a)
     88 {
     89     if (u==ed) return a;
     90     int aug=0, delta;
     91     for(int &i=cur[u]; i!=-1; i=edge[i].next)
     92     {
     93         int v=edge[i].v;
     94         int w=edge[i].cap-edge[i].flow;
     95         if (w>0 && d[v]==d[u]+1)
     96         {
     97             delta = Aug(v, min(a,w));
     98             if (delta)
     99             {
    100                 edge[i].flow += delta;
    101                 edge[i^1].flow -= delta;
    102                 aug += delta;
    103                 if (!(a-=delta)) break;
    104             }
    105         }
    106     }
    107     if (!aug) d[u]=-1;
    108     return aug;
    109 }
    110 int Dinic(int NdFlow)
    111 {
    112     int flow=0;
    113     while (BFS())
    114     {
    115         memcpy(cur,head,sizeof(int)*(n+1));
    116         flow += Aug(st,inf);
    117         /*如果超过指定流量就return 掉*/
    118         if(NdFlow==inf) continue;
    119         if(flow > NdFlow) break;
    120     }
    121     return flow;
    122 }
    123 /*残余网络*/
    124 void Reduce()
    125 {
    126     for(int i=0; i<edgeNum; i++) edge[i].cap-=edge[i].flow;
    127 }
    128 /*清空流量*/
    129 void ClearFlow()
    130 {
    131     for(int i=0; i<edgeNum; i++) edge[i].flow=0;
    132 }
    133 /*求最小割*/
    134 vector<int> MinCut()
    135 {
    136     BFS();
    137     vector<int> ans;
    138     for(int u=0; u<n; u++)
    139     {
    140         if(!vis[u]) continue;
    141         for(int i=head[u]; i!=-1; i=edge[i].next)
    142         {
    143             if(i&1) continue;/*忽略反向边*/
    144             int v=edge[i].v;
    145             int w=edge[i].cap;
    146             if(!vis[v]&&w>0) ans.push_back(i);
    147         }
    148     }
    149     return ans;
    150 }
    151 
    152 /**
    153 *贪心预流:用于分层图Dinic预处理(从0到n-1)
    154 *输入:图(链式前向星),n(顶点个数,包含源汇),st(源),ed(汇),rk[i]=i,level[](分层图的层次)
    155 *输出:GreedyPreFlow()(预处理Dinic)
    156 */
    157 int in[maxn],out[maxn];
    158 int level[maxn],rk[maxn];
    159 bool cmp(const int &i,const int &j)
    160 {
    161     return level[i]<level[j];
    162 }
    163 void GreedyPreFlow()
    164 {
    165     memset(in, 0, sizeof (in));
    166     memset(out, 0, sizeof (out));
    167     sort(rk, rk+n, cmp);
    168     in[st] = inf;
    169     for (int i = 0; i < n; ++i)
    170     {
    171         int u = rk[i];
    172         for (int j = head[u]; j!=-1; j = edge[j].next)
    173         {
    174             int v = edge[j].v, w = edge[j].cap-edge[j].flow;
    175             if (!(j & 1) && in[u] > out[u])
    176             {
    177                 int f = min(w, in[u]-out[u]);
    178                 in[v] += f, out[u] += f;
    179             }
    180         }
    181     }
    182     memset(in, 0, sizeof (in));
    183     in[ed] = inf;
    184     for (int i = n-1; i >= 0; --i)
    185     {
    186         int v = rk[i];
    187         for (int j = head[v]; j!=-1; j = edge[j].next)
    188         {
    189             int u = edge[j].v, w = edge[j^1].cap-edge[j^1].flow;
    190             if (j & 1 && out[u] > in[u])
    191             {
    192                 int f = min(w, min(out[u]-in[u], in[v]));
    193                 in[u] += f, in[v] -= f;
    194                 edge[j].flow -= f, edge[j^1].flow += f;
    195             }
    196         }
    197     }
    198 }
    199 
    200 int N,M,L;
    201 void init()
    202 {
    203     memset(head,-1,sizeof(head));
    204     edgeNum=0;
    205 }
    206 void input()
    207 {
    208     scanf("%d%d%d",&N,&M,&L);
    209     int x=0;
    210     int idx=0;
    211     st=0,ed=0;
    212     for(int i=0; i<N; i++)
    213     {
    214         scanf("%d",&x);
    215         rk[i]=i;
    216         level[i]=x;
    217         if(x==1) st=i;
    218         if(x==L) ed=i;
    219     }
    220     for(int i=0; i<M; i++)
    221     {
    222         int u,v,w;
    223         scanf("%d%d%d",&u,&v,&w);
    224         u--,v--;
    225         addEdge(u,v,w);
    226     }
    227     n=N;
    228 }
    229 void solve()
    230 {
    231     GreedyPreFlow();
    232     ISAP(inf);
    233 //    cout<<HLPP()<<endl;
    234 //    cout<<Dinic(inf)<<endl;
    235     for(int i=0; i<edgeNum; i+=2) printf("%d
    ",edge[i].flow);
    236 }
    237 void output()
    238 {
    239     //
    240 }
    241 int main()
    242 {
    243 //    std::ios_base::sync_with_stdio(false);
    244 //    freopen("in.cpp","r",stdin);
    245     int T;
    246     scanf("%d",&T);
    247     while(T--)
    248     {
    249         init();
    250         input();
    251         solve();
    252         output();
    253     }
    254     return 0;
    255 }
    View Code
  • 相关阅读:
    .NET Interop 工具集
    关于正弦波的算法
    Windows Phone 系列 本地数据存储
    Xaml cannot create an instance of “X”
    Windows Phone 系列 使用 MVVM绑定时无法获取当前值
    Windows Phone 系列 应用程序图标无法显示
    Windows Phone 系列 WPConnect无法上网的问题
    Windows Phone 系列 使用 Windows Phone 保存铃声任务
    WP7.5提交应用
    Windows Phone 系列 动态删除ObservableCollection
  • 原文地址:https://www.cnblogs.com/xysmlx/p/3338605.html
Copyright © 2011-2022 走看看