zoukankan      html  css  js  c++  java
  • HDU

    题意:给定一个n个点m条边的有向图,每条边有个长度,可以花费等同于其长度的代价将其破坏掉,求最小的花费使得从1到n的最短路变长。

    解法:先用dijkstra求出以1为源点的最短路,并建立最短路图(只保留d[v]=d[u]+e[i].c的边(u,v)),跑个最大流即可。

    Dinic:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 const ll N=1e4+10,inf=0x3f3f3f3f3f3f3f3fll;
     5 ll n,m;
     6 struct MF {
     7     ll hd[N],ne,d[N],g[N],cur[N];
     8     struct E {ll v,cp,nxt;} e[N<<2];
     9     void init() {memset(hd,-1,sizeof hd),ne=0;}
    10     void addedge(ll u,ll v,ll cp) {
    11         e[ne]= {v,cp,hd[u]},hd[u]=ne++;
    12         e[ne]= {u,0,hd[v]},hd[v]=ne++;
    13     }
    14     int bfs(ll s,ll t) {
    15         queue<ll> q;
    16         memset(d,-1,sizeof d);
    17         d[s]=0,q.push(s);
    18         while(q.size()) {
    19             ll u=q.front();
    20             q.pop();
    21             for(ll i=hd[u]; ~i; i=e[i].nxt)if(e[i].cp) {
    22                     ll v=e[i].v;
    23                     if(!~d[v])d[v]=d[u]+1,q.push(v);
    24                 }
    25         }
    26         return ~d[t];
    27     }
    28     ll dfs(ll t,ll u,ll f) {
    29         if(u==t||!f)return f;
    30         ll ret=0;
    31         for(ll& i=cur[u]; ~i; i=e[i].nxt) {
    32             ll v=e[i].v;
    33             if(d[v]==d[u]+1) {
    34                 ll df=dfs(t,v,min(f,e[i].cp));
    35                 e[i].cp-=df,e[i^1].cp+=df,f-=df,ret+=df;
    36                 if(!f)return ret;
    37             }
    38         }
    39         return ret;
    40     }
    41     ll dinic(ll s,ll t) {
    42         ll ret=0;
    43         while(bfs(s,t)) {
    44             for(ll i=1; i<=n; ++i)cur[i]=hd[i];
    45             ret+=dfs(t,s,inf);
    46         }
    47         return ret;
    48     }
    49 } mf;
    50 struct SP {
    51     ll hd[N],ne,dp[N];
    52     struct E {ll v,c,nxt;} e[N];
    53     void init() {memset(hd,-1,sizeof hd),ne=0;}
    54     void addedge(ll u,ll v,ll c) {e[ne]= {v,c,hd[u]},hd[u]=ne++;}
    55     struct D {
    56         ll u,g;
    57         bool operator<(const D& b)const {return b.g>g;}
    58     };
    59     priority_queue<D> q;
    60     void upd(ll u,ll ad) {if(dp[u]>ad)dp[u]=ad,q.push({u,ad});}
    61     void dij(ll s) {
    62         memset(dp,inf,sizeof dp);
    63         upd(s,0);
    64         while(q.size()) {
    65             ll u=q.top().u,g=q.top().g;
    66             q.pop();
    67             if(dp[u]!=g)continue;
    68             for(ll i=hd[u]; ~i; i=e[i].nxt) {
    69                 ll v=e[i].v,c=e[i].c;
    70                 upd(v,g+c);
    71             }
    72         }
    73     }
    74     void solve() {
    75         dij(1);
    76         for(ll u=1; u<=n; ++u) {
    77             for(ll i=hd[u]; ~i; i=e[i].nxt) {
    78                 ll v=e[i].v,c=e[i].c;
    79                 if(dp[v]==dp[u]+c)mf.addedge(u,v,c);
    80             }
    81         }
    82         printf("%lld
    ",mf.dinic(1,n));
    83     }
    84 } sp;
    85 int main() {
    86     ll T;
    87     for(scanf("%lld",&T); T--;) {
    88         sp.init(),mf.init();
    89         scanf("%lld%lld",&n,&m);
    90         while(m--) {
    91             ll u,v,c;
    92             scanf("%lld%lld%lld",&u,&v,&c);
    93             sp.addedge(u,v,c);
    94         }
    95         sp.solve();
    96     }
    97     return 0;
    98 }

    ISAP:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 const ll N=1e4+10,inf=0x3f3f3f3f3f3f3f3fll;
     5 ll n,m;
     6 struct MF {
     7     ll hd[N],ne,d[N],g[N],cur[N];
     8     struct E {ll v,cp,nxt;} e[N<<2];
     9     void init() {memset(hd,-1,sizeof hd),ne=0;}
    10     void addedge(ll u,ll v,ll cp) {
    11         e[ne]= {v,cp,hd[u]},hd[u]=ne++;
    12         e[ne]= {u,0,hd[v]},hd[v]=ne++;
    13     }
    14     void bfs(ll s) {
    15         queue<ll> q;
    16         memset(d,-1,sizeof d);
    17         memset(g,0,sizeof g);
    18         ++g[d[s]=0],q.push(s);
    19         while(q.size()) {
    20             ll u=q.front();
    21             q.pop();
    22             for(ll i=hd[u]; ~i; i=e[i].nxt) {
    23                 ll v=e[i].v;
    24                 if(!~d[v])++g[d[v]=d[u]+1],q.push(v);
    25             }
    26         }
    27     }
    28     ll dfs(ll s,ll t,ll u,ll f) {
    29         if(u==t||!f)return f;
    30         ll ret=0;
    31         for(ll& i=cur[u]; ~i; i=e[i].nxt) {
    32             ll v=e[i].v;
    33             if(d[v]==d[u]-1) {
    34                 ll df=dfs(s,t,v,min(f,e[i].cp));
    35                 e[i].cp-=df,e[i^1].cp+=df,f-=df,ret+=df;
    36                 if(!f)return ret;
    37             }
    38         }
    39         if(!--g[d[u]])d[s]=n+1;
    40         ++g[++d[u]],cur[u]=hd[u];
    41         return ret;
    42     }
    43     ll isap(ll s,ll t) {
    44         ll ret=0;
    45         bfs(t);
    46         for(ll i=1; i<=n; ++i)cur[i]=hd[i];
    47         while(d[s]<n+1)ret+=dfs(s,t,s,inf);
    48         return ret;
    49     }
    50 } mf;
    51 struct SP {
    52     ll hd[N],ne,dp[N];
    53     struct E {ll v,c,nxt;} e[N];
    54     void init() {memset(hd,-1,sizeof hd),ne=0;}
    55     void addedge(ll u,ll v,ll c) {e[ne]= {v,c,hd[u]},hd[u]=ne++;}
    56     struct D {
    57         ll u,g;
    58         bool operator<(const D& b)const {return b.g>g;}
    59     };
    60     priority_queue<D> q;
    61     void upd(ll u,ll ad) {if(dp[u]>ad)dp[u]=ad,q.push({u,ad});}
    62     void dij(ll s) {
    63         memset(dp,inf,sizeof dp);
    64         upd(s,0);
    65         while(q.size()) {
    66             ll u=q.top().u,g=q.top().g;
    67             q.pop();
    68             if(dp[u]!=g)continue;
    69             for(ll i=hd[u]; ~i; i=e[i].nxt) {
    70                 ll v=e[i].v,c=e[i].c;
    71                 upd(v,g+c);
    72             }
    73         }
    74     }
    75     void solve() {
    76         dij(1);
    77         for(ll u=1; u<=n; ++u) {
    78             for(ll i=hd[u]; ~i; i=e[i].nxt) {
    79                 ll v=e[i].v,c=e[i].c;
    80                 if(dp[v]==dp[u]+c)mf.addedge(u,v,c);
    81             }
    82         }
    83         printf("%lld
    ",mf.isap(1,n));
    84     }
    85 } sp;
    86 int main() {
    87     ll T;
    88     for(scanf("%lld",&T); T--;) {
    89         sp.init(),mf.init();
    90         scanf("%lld%lld",&n,&m);
    91         while(m--) {
    92             ll u,v,c;
    93             scanf("%lld%lld%lld",&u,&v,&c);
    94             sp.addedge(u,v,c);
    95         }
    96         sp.solve();
    97     }
    98     return 0;
    99 }

    这道题Dinic居然比ISAP快,我的代码ISAP跑了156ms,而Dinic只跑了93ms..

  • 相关阅读:
    毕业季 | 如何做出99分的答辩PPT
    git: error setting certificate verify locations解决办法
    获取表格里面的内容
    MD5加密算法
    mybatis多条件批量删除
    layer.confirm
    DevExpress控件的GridControl实现行多选
    sz与rz命令
    @TableField的使用
    C# WinForm 中Label自动换行 解决方法
  • 原文地址:https://www.cnblogs.com/asdfsag/p/11262488.html
Copyright © 2011-2022 走看看