zoukankan      html  css  js  c++  java
  • hdu 6852Path6(最短路+最小割)

    传送门

    •题意

    有n个城市,标号1-n

    现花费最小的代价堵路

    使得从1号城市到n号城市的路径边长

    (注意只是变长不是最长)

    堵一条路的代价是这条路的权值

    •思路

    在堵路以前,从1到n的最小路径当然是最短路

    想要路径边长就要在最短路上动手脚

    把从1到n的最短路找出来形成一个最短路图,

    然后用最小的代价使得最短路图不连通

    也就是求这个最短路图的最小割

    那怎么建这个最短路图呢?

    分别以1和n为源点跑一遍dijkstra,找出每个点到1和n的最短路

    设$dis[1][i]$为1到i的最短路,$dis[n][i]$为i到n的最短路

    $1->u->v->n$是$1->n$的一条最短路即$dis[1][u]+w[u->v]+dis[n][v]=dis[1][n]$

    那么,u->v是1->n最短路上的一条边,加入最短路图中

    (由于代码被某人嫌弃太乱,所以对dijkstra和dinic封装了一下...)

    •代码

    (未封装版)

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 #define mem(a,b) memset(a,b,sizeof(a))
      4 #define ll long long
      5 #define INF 0x3f3f3f3f3f3f3f3f
      6 #define P pair<long long,int>
      7 const int maxn=1e5+5;
      8 int n,m;
      9 struct Edge
     10 {
     11     int v;
     12     ll w;
     13     int next;
     14 }de[maxn],fe[maxn],e[maxn];
     15 
     16 int head1[maxn],head2[maxn];
     17 int cnt1,cnt2;
     18 void add(int u,int v,ll w)
     19 {
     20     de[++cnt1]={v,w,head1[u]};
     21     head1[u]=cnt1;
     22 
     23     fe[++cnt2]={u,w,head2[v]};
     24     head2[v]=cnt2;
     25 }
     26 
     27 ll dis1[maxn],disn[maxn];
     28 bool vis1[maxn],visn[maxn];
     29 priority_queue<P,vector<P>,greater<P> >pq;
     30 
     31 void dijkstra()
     32 {
     33     while(!pq.empty())
     34         pq.pop();
     35     for(int i=1;i<=n;i++)
     36         dis1[i]=INF,vis1[i]=0;
     37     dis1[1]=0;
     38     pq.push(make_pair(0,1));
     39     while(!pq.empty())
     40     {
     41         int u=pq.top().second;
     42         pq.pop();
     43         if(!vis1[u])
     44         {
     45             vis1[u]=1;
     46             for(int i=head1[u];~i;i=de[i].next)
     47             {
     48                 int v=de[i].v;
     49                 dis1[v]=min(dis1[v],dis1[u]+de[i].w);
     50                 pq.push(make_pair(dis1[v],v));
     51             }
     52         }
     53     }
     54 
     55     while(!pq.empty())
     56         pq.pop();
     57     for(int i=1;i<=n;i++)
     58         disn[i]=INF,visn[i]=0;
     59     disn[n]=0;
     60 
     61     pq.push(make_pair(0,n));
     62     while(!pq.empty())
     63     {
     64         int u=pq.top().second;
     65         pq.pop();
     66         if(!visn[u])
     67         {
     68             visn[u]=1;
     69             for(int i=head2[u];~i;i=fe[i].next)
     70             {
     71                 int v=fe[i].v;
     72                 disn[v]=min(disn[v],disn[u]+fe[i].w);
     73                 pq.push(make_pair(disn[v],v));
     74             }
     75         }
     76     }
     77 }
     78 
     79 int head[maxn],cnt;
     80 int cur[maxn],d[maxn];
     81 void addEdge(int u,int v,ll w)
     82 {
     83     e[++cnt]={v,w,head[u]};
     84     head[u]=cnt;
     85 
     86     e[++cnt]={u,0,head[v]};
     87     head[v]=cnt;
     88 }
     89 
     90 bool bfs()
     91 {
     92     queue<int> q;
     93     for(int i=1;i<=n;i++)
     94         d[i]=-1;
     95     d[1]=0;
     96     q.push(1);
     97     while(!q.empty())
     98     {
     99         int u=q.front();
    100         q.pop();
    101         for(int i=head[u];~i;i=e[i].next)
    102         {
    103             int v=e[i].v;
    104             if(d[v]==-1&&e[i].w>0)
    105             {
    106                 d[v]=d[u]+1;
    107                 q.push(v);
    108             }
    109         }
    110     }
    111     return d[n]!=-1;
    112 }
    113 
    114 ll dfs(int u,ll flow)
    115 {
    116     ll nowflow=0;
    117     if(u==n) return flow;
    118     for(int i=cur[u];~i;i=e[i].next)
    119     {
    120         cur[u]=i;
    121         int v=e[i].v;
    122         if(d[v]==d[u]+1&&e[i].w>0)
    123         {
    124             ll k=dfs(v,min(flow-nowflow,e[i].w));
    125             if(k)
    126             {
    127                 nowflow+=k;
    128                 e[i].w-=k;
    129                 e[i^1].w+=k;
    130                 if(nowflow==flow)
    131                     break;
    132             }
    133         }
    134     }
    135     if(!nowflow) d[u]=-2;
    136     return nowflow;
    137 }
    138 
    139 ll Dinic()
    140 {
    141     ll ans=0;
    142     while(bfs())
    143     {
    144         for(int i=1;i<=n;i++)
    145             cur[i]=head[i];
    146 
    147         ans+=dfs(1,INF);
    148     }
    149     return ans;
    150 }
    151 
    152 
    153 
    154 void Init()
    155 {
    156     mem(head1,-1);
    157     mem(head2,-1);
    158     mem(head,-1);
    159     cnt1=cnt2=cnt=-1;
    160 }
    161 
    162 int main()
    163 {
    164 //    freopen("C:\Users\14685\Desktop\C++workspace\in&out\contest","r",stdin);
    165     int T;
    166     scanf("%d",&T);
    167     while(T--)
    168     {
    169         scanf("%d%d",&n,&m);
    170         Init();
    171         for(int i=1;i<=m;i++)
    172         {
    173             int u,v;
    174             ll w;
    175             scanf("%d%d%lld",&u,&v,&w);
    176             add(u,v,w);
    177         }
    178 
    179         dijkstra();
    180 
    181         for(int u=1;u<=n;u++)
    182         {
    183             for(int i=head1[u];~i;i=de[i].next)
    184             {
    185                 int v=de[i].v;
    186                 if(dis1[u]+disn[v]+de[i].w==dis1[n])
    187                 {
    188 //                    printf("***%d %d %d
    ",u,v,de[i].w);
    189                     addEdge(u,v,de[i].w);
    190                 }
    191             }
    192         }
    193 
    194         printf("%lld
    ",Dinic());
    195     }
    196 }
    View Code

    (封装版)

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 #define ll long long
      4 #define pli pair<ll,int>
      5 #define INF 0x3f3f3f3f3f3f3f3f
      6 #define mem(a,b) memset(a,b,sizeof(a))
      7 const int maxn=1e5+5;
      8 int n,m;
      9 struct Edge
     10 {
     11     int v;
     12     ll w;
     13     int next;
     14 }G[maxn<<1],e[maxn<<1];
     15 int dhead[maxn],dcnt;
     16 void addEdge(int u,int v,ll w)
     17 {
     18     G[++dcnt]={v,w,dhead[u]};
     19     dhead[u]=dcnt;
     20 }
     21 
     22 struct Dij
     23 {
     24     ll dis[2][maxn];
     25     bool vis[maxn];
     26     priority_queue<pli,vector<pli>,greater<pli> > q;
     27     void dij(int s,int n,bool ok)
     28     {
     29         for(int i=1;i<=n;i++)
     30             dis[ok][i]=INF,vis[i]=0;
     31         dis[ok][s]=0;
     32         q.push({0,s});
     33         while(!q.empty())
     34         {
     35             int u=q.top().second;
     36             q.pop();
     37             if(vis[u])
     38                 continue;
     39             vis[u]=1;
     40             for(int i=dhead[u];~i;i=G[i].next)
     41             {
     42                 ///偶数是正向边,ok=true是正向边
     43                 if(ok && i&1)
     44                     continue;
     45                 ///奇数是反向边,ok=false是反向边
     46                 if(!ok && !(i&1))
     47                     continue;
     48 
     49                 int v=G[i].v;
     50                 ll w=G[i].w;
     51                 if(dis[ok][v]>dis[ok][u]+w)
     52                 {
     53                     dis[ok][v]=dis[ok][u]+w;
     54                     if(!vis[v])
     55                         q.push({dis[ok][v],v});
     56                 }
     57             }
     58         }
     59     }
     60 }dij;
     61 
     62 int head[maxn],cnt;
     63 void add(int u,int v,ll w)
     64 {
     65     e[++cnt]={v,w,head[u]};
     66     head[u]=cnt;
     67 }
     68 struct Dinic
     69 {
     70     int cur[maxn],d[maxn];
     71     int s=1,t=n;
     72     bool bfs()
     73     {
     74         queue<int> q;
     75         for(int i=1;i<=n;i++)
     76             d[i]=-1;
     77         d[1]=0;
     78         q.push(1);
     79         while(!q.empty())
     80         {
     81             int u=q.front();
     82             q.pop();
     83             for(int i=head[u];~i;i=e[i].next)
     84             {
     85                 int v=e[i].v;
     86                 if(d[v]==-1&&e[i].w>0)
     87                 {
     88                     d[v]=d[u]+1;
     89                     q.push(v);
     90                 }
     91             }
     92         }
     93         return d[n]!=-1;
     94     }
     95 
     96     ll dfs(int u,ll flow)
     97     {
     98         ll nowflow=0;
     99         if(u==n) return flow;
    100         for(int i=cur[u];~i;i=e[i].next)
    101         {
    102             cur[u]=i;
    103             int v=e[i].v;
    104             if(d[v]==d[u]+1&&e[i].w>0)
    105             {
    106                 ll k=dfs(v,min(flow-nowflow,e[i].w));
    107                 if(k)
    108                 {
    109                     nowflow+=k;
    110                     e[i].w-=k;
    111                     e[i^1].w+=k;
    112                     if(nowflow==flow)
    113                         break;
    114                 }
    115             }
    116         }
    117         if(!nowflow) d[u]=-2;
    118         return nowflow;
    119     }
    120 
    121     ll din()
    122     {
    123         ll ans=0;
    124         while(bfs())
    125         {
    126             for(int i=1;i<=n;i++)
    127                 cur[i]=head[i];
    128 
    129             ans+=dfs(1,INF);
    130         }
    131         return ans;
    132     }
    133 }_din;
    134 
    135 void Init()
    136 {
    137     mem(dhead,-1);
    138     dcnt=-1;
    139     mem(head,-1);
    140     cnt=-1;
    141 }
    142 
    143 int main()
    144 {
    145     int T;
    146     scanf("%d",&T);
    147     while(T--)
    148     {
    149         Init();
    150         scanf("%d%d",&n,&m);
    151         for(int i=1;i<=m;i++)
    152         {
    153             int u,v;
    154             ll w;
    155             scanf("%d%d%lld",&u,&v,&w);
    156             ///跑1到其他点的最短路 加正向边
    157             addEdge(u,v,w);
    158             ///跑n到其他点的最短路 加反向边
    159             addEdge(v,u,w);
    160         }
    161 
    162         dij.dij(1,n,true);
    163         dij.dij(n,n,false);
    164 
    165 
    166         for(int u=1;u<=n;u++)
    167         {
    168             for(int i=dhead[u];~i;i=G[i].next)
    169             {
    170                 int v=G[i].v;
    171                 ll w=G[i].w;
    172                 if(dij.dis[1][u]+dij.dis[0][v]+w==dij.dis[1][n])
    173                 {
    174                     add(u,v,w);
    175                     add(v,u,0);
    176                 }
    177             }
    178         }
    179         printf("%lld
    ",_din.din());
    180     }
    181 }
    View Code
  • 相关阅读:
    hive报错 java.sql.SQLException: No suitable driver found for jdbc:hive://localhost:10000/default
    使用Beeline连接Hive
    hive报错 root is not allowed to impersonate root (state=08S01,code=0)
    hive报错 Could not open client transport with JDBC Uri: jdbc:hive2://node01:10000/default:java.net.ConnectException refused
    excel快速删除空值单元格,数据上移
    FineBI 图表选择
    数据库连接池大小设置?
    工作中有待留❤️积累的一些经验
    内存包括随机存储器(RAM),只读存储器(ROM),以及高速缓存(CACHE)。RAM最重要
    我自己ood的复习思路:抄
  • 原文地址:https://www.cnblogs.com/MMMinoz/p/11599641.html
Copyright © 2011-2022 走看看