Path HDU - 6582 [for the most minimal cut short-circuit all sides +]

Meaning of the questions:

  For a directed graph, each edge cost of deleting the length of a side, with minimum effort required, such that 1 n 1\to n shortest path becomes long, the required minimum cost.

Ideas:

  To make the most shorted longer, then remove side must destroy the original shortest. That is, to put all the shortest of all sides to find out, by removing a few edges, so that all of the shortest path is invalid.
  How all sides to find the shortest of all of it? With d i s 1 [ i ] dis1 [i] represented by the artwork, 1 1 No. Node remaining nodes of the shortest distance; to d i s 2 [ i ] dis2[i] represents the reverse construction of FIG. n n number of minimum distance from the node to the respective nodes. If the edge is an edge, the two end points assuming shortest path u in sum v v , the right side is w w , there are:
d i s 1 [ u ] + w + d i s 2 [ v ] = d i s 1 [ n ] dis1[u]+w+dis2[v]=dis1[n]
So, after forward and reverse run twice built FIG shortest traversing all edges can be determined.
Then there are deleted in the side on the edges of the map built so that 1 1 and n n is not connected dots. Minimal Cut obviously.
Theoretically D i n i c Dinic time complexity is O ( n 2 m ) O(n^2*m) , but in fact superior to the more.
AC Code:

#include <bits/stdc++.h>//把所有最短路的所有边找出,然后跑最大流
using namespace std;
typedef long long ll;
typedef pair<ll,int> P;
const int N=1e4+5;
const ll inf=1e16;//注意取值范围设置合理的inf,WA的好惨
struct edge
{
    int from;
    int too;
    ll val;
};
struct node
{
    int to;
    ll val;
    int rev;
};
vector<P>pic[2][N];//正向和反向边
vector<edge>eg;//存边
vector<node>pa[N];//网络流的图
priority_queue<P,vector<P>,greater<P> >que;
queue<int>q;
ll dis[2][N];
int layer[N],iter[N];
int n;
void init()
{
    for(int j=0;j<2;j++)
    {
        for(int i=0;i<=n;i++)
            pic[j][i].clear();
        for(int i=0;i<=n;i++)
            dis[j][i]=inf;
    }
    eg.clear();
    for(int i=0;i<=n;i++)
        pa[i].clear();
}
void dij(int s)
{
    while(!que.empty())
        que.pop();
    if(s==0)
    {
        que.push(make_pair(0,1));
        dis[s][1]=0;
    }
    else
    {
        que.push(make_pair(0,n));
        dis[s][n]=0;
    }
    while(!que.empty())
    {
        P now=que.top();
        que.pop();
        if(now.first>dis[s][now.second])
            continue;
        for(int i=0;i<pic[s][now.second].size();i++)
        {
            P tmp=pic[s][now.second][i];
            if(tmp.first+dis[s][now.second]<dis[s][tmp.second])
            {
                dis[s][tmp.second]=tmp.first+dis[s][now.second];
                que.push(make_pair(dis[s][tmp.second],tmp.second));
            }
        }
    }
}
void addedge(int u,int v,ll w)
{
    pa[u].push_back(node{v,w,pa[v].size()});
    pa[v].push_back(node{u,0,pa[u].size()-1});
}
bool bfs()
{
    while(!q.empty())
        q.pop();
    fill(layer,layer+n+1,-1);
    layer[1]=0;
    q.push(1);
    while(!q.empty())
    {
        int now=q.front();
        q.pop();
        for(int i=0;i<pa[now].size();i++)
        {
            node t=pa[now][i];
            if(layer[t.to]<0&&t.val>0)
            {
                layer[t.to]=layer[now]+1;
                q.push(t.to);
                if(t.to==n)
                    return true;
            }
        }
    }
    return false;
}
ll dfs(int v,ll w)
{
    if(v==n)
        return w;
    for(int &i=iter[v];i<pa[v].size();i++)
    {
        node &e=pa[v][i];//cout<<"val="<<e.val<<endl;
        if(e.val>0&&layer[e.to]>layer[v])
        {
            ll d=dfs(e.to,min(w,e.val));
            if(d>0)
            {
                e.val-=d;
                pa[e.to][e.rev].val+=d;
                return d;
            }
        }
    }
    return 0;
}
ll dinic()
{
  ll maxflow=0;
  while(bfs())
  {
      ll f=0;
      fill(iter,iter+1+n,0);
      while((f=dfs(1,inf))>0)
        maxflow+=f;//,cout<<"f="<<f<<endl;
  }
  return maxflow;
}
int main()
{
    int t,m;
    scanf("%d",&t);
    while(t--)
    {
        int u,v;
        ll w;
        scanf("%d%d",&n,&m);
        init();
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d%lld",&u,&v,&w);
            pic[0][u].push_back(make_pair(w,v));
            pic[1][v].push_back(make_pair(w,u));
            eg.push_back(edge{u,v,w});
        }
        dij(0);
        dij(1);
        for(int i=0;i<eg.size();i++)
        {
            if(dis[0][eg[i].from]+dis[1][eg[i].too]+eg[i].val==dis[0][n])
                addedge(eg[i].from,eg[i].too,eg[i].val);
        }
        printf("%lld\n",dinic());
    }
    return 0;
}

Published 121 original articles · won praise 11 · views 2107

Guess you like

Origin blog.csdn.net/weixin_43184669/article/details/104417420