[2019杭电多校第一场][hdu6582]Path

Posted sainsist

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[2019杭电多校第一场][hdu6582]Path相关的知识,希望对你有一定的参考价值。

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6582

题意:删掉边使得1到n的最短路改变,删掉边的代价为该边的边权。求最小代价。

比赛时一片浆糊,赛后听到dinic瞬间思维通透XD

大致做法就是先跑一边最短路,然后再保留所有满足dis[i]+w==dis[j]的边,在这些边上跑最小割(dinic)。

代码写的异常丑陋,见谅QAQ

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstdlib>
  4 #include<algorithm>
  5 #include<cstring>
  6 #include<string>
  7 #include<queue>
  8 using namespace std;
  9 typedef long long ll;
 10 const ll maxn = 3e5 + 10;
 11 const ll inf = 1e18;
 12 struct node 
 13     ll s, e, next;
 14     ll w;
 15 edge[maxn * 2], edge2[maxn * 2];
 16 ll head[maxn], head2[maxn], len, len2;
 17 void init() 
 18     memset(head, -1, sizeof(head));
 19     memset(head2, -1, sizeof(head2));
 20     len = len2 = 0;
 21 
 22 void add(ll s, ll e, ll w) 
 23     edge[len].s = s;
 24     edge[len].e = e;
 25     edge[len].w = w;
 26     edge[len].next = head[s];
 27     head[s] = len++;
 28 
 29 void add2(ll s, ll e, ll w) 
 30     edge2[len2].s = s;
 31     edge2[len2].e = e;
 32     edge2[len2].w = w;
 33     edge2[len2].next = head2[s];
 34     head2[s] = len2++;
 35 
 36 struct p 
 37     ll dis, num;
 38     bool operator<(const p&a)const 
 39         return a.dis < dis;
 40     
 41 ;
 42 ll dis[maxn];
 43 ll vis[maxn];
 44 void dij(ll n) 
 45     priority_queue<p>q;
 46     for (ll i = 1; i <= n; i++)
 47         dis[i] = inf, vis[i] = 0;
 48     q.push( 0ll,1ll );
 49     dis[1] = 0ll;
 50     while (!q.empty()) 
 51         ll x = q.top().num;
 52         q.pop();
 53         if (vis[x])
 54             continue;
 55         vis[x] = 1;
 56         for (ll i = head[x]; i != -1; i = edge[i].next) 
 57             ll y = edge[i].e;
 58             if (dis[y] > dis[x] + edge[i].w) 
 59                 dis[y] = dis[x] + edge[i].w;
 60                 q.push( dis[y],y );
 61             
 62         
 63     
 64 
 65 ll d[maxn];
 66 bool bfs(ll s, ll t) 
 67     queue<ll>q;
 68     memset(d, 0, sizeof(d));
 69     d[s] = 1ll;
 70     q.push(s);
 71     while (!q.empty()) 
 72         ll x = q.front(); q.pop();
 73         for (ll i = head2[x]; i != -1; i = edge2[i].next) 
 74             ll y = edge2[i].e;
 75             if (edge2[i].w && !d[y]) 
 76                 d[y] = d[x] + 1ll;
 77                 q.push(y);
 78             
 79         
 80     
 81     return d[t];
 82 
 83 ll dfs(ll x, ll t, ll limit) 
 84     if (x == t)
 85         return limit;
 86     ll add, ans = 0;
 87     for (ll i = head2[x]; i != -1; i = edge2[i].next) 
 88         ll y = edge2[i].e;
 89         if (d[y] == d[x] + 1 && edge2[i].w) 
 90             add = dfs(y, t, min(limit, edge2[i].w));
 91             edge2[i].w -= add;
 92             edge2[i ^ 1].w += add;
 93             ans += add;
 94             limit -= add;
 95             if (!limit)
 96                 break;
 97         
 98     
 99     if (!ans)
100         d[x] = -1;
101     return ans;
102 
103 ll dinic(ll s, ll t) 
104     ll ans = 0;
105     while (bfs(s, t))
106         ans += dfs(s, t, inf);
107     return ans;
108 
109 int main() 
110     ll t;
111     scanf("%lld", &t);
112     while (t--) 
113         ll n, m;
114         init();
115         scanf("%lld%lld", &n, &m);
116         ll x, y, z;
117         for (ll i = 1; i <= m; i++) 
118             scanf("%lld%lld%lld", &x, &y, &z);
119             add(x, y, z);
120         
121         dij(n);
122         for (ll i = 1; i <= n; i++)
123             for (ll j = head[i]; j != -1; j = edge[j].next)
124                 if (dis[edge[j].s] + edge[j].w == dis[edge[j].e])
125                     add2(edge[j].s, edge[j].e, edge[j].w), add2(edge[j].e, edge[j].s, 0ll);
126         printf("%lld\n", dinic(1, n));
127     
128     return 0;
129 

 

以上是关于[2019杭电多校第一场][hdu6582]Path的主要内容,如果未能解决你的问题,请参考以下文章

[2019杭电多校第一场][hdu6578]Blank

2019杭电多校第一场 Operation HDU - 6579

2019.07.222019杭电多校第一场

2019杭电多校第一场hdu6581 Vacation

2019 杭电多校第一场

2019杭电多校第一场