【Nowcoder】[AHOI2006]上学路线ROUTE | 最短路、最小割

题目链接:https://ac.nowcoder.com/acm/problem/19874

题目大意:

给出一张图,每条边都有一个时间与花费,问1~n的最短路 和 最少花费使得1~n的最短路边大

题目思路:

1~n的最短路变大,那么就需要破坏最短路图

所以也就是将最短路图还原出来

之后再最短路图上跑最小割即可

被最短路卡的疯狂wa 不知道spfa还原问题出在哪~

Code:

/*** keep hungry and calm CoolGuang!***/
#pragma GCC optimize(3)
#include 
#define debug(x) cout<<#x<<":"< pp;
const ll INF=1e17;
const int Maxn=1e6+10;
const int maxn =1e5+10;
const int mod= 1e9+7;
const int Mod = 1e6+7;
///const double eps=1e-10;
inline bool read(ll &num)
{char in;bool IsN=false;
    in=getchar();if(in==EOF) return false;while(in!='-'&&(in<'0'||in>'9')) in=getchar();if(in=='-'){ IsN=true;num=0;}else num=in-'0';while(in=getchar(),in>='0'&&in<='9'){num*=10,num+=in-'0';}if(IsN) num=-num;return true;}
ll n,m,p;
vector>v[maxn];
ll t[maxn],c[maxn];
ll x[maxn],y[maxn];
ll dis_s[maxn],dis_t[maxn];
int vis[maxn];
ll S,T;
ll cnt = 2;
int head[maxn],cur[maxn];
ll flow[maxn];
struct node{
    int e,next;
    ll w;
}edge[maxn];
void addedge(int u,int v,ll w){
    edge[cnt] = node{v,head[u],w};
    head[u] = cnt++;
}
int d[maxn];
void spfa(int s,ll *p){
    for(int i=1;i<=n;i++) p[i] = INF,vis[i] = 0;
    queueq;q.push(s);vis[s] = 1;p[s] = 0;
    while(!q.empty()){
        int u = q.front();q.pop();vis[u] = 0;
        for(auto x:v[u]){
            int id = x.second, e = x.first;
            if(p[e]>p[u]+t[id]){
                p[e] = p[u] + t[id];
                if(!vis[e]){
                    vis[e] = 1;
                    q.push(e);
                }
            }
        }
    }return;
}
void TraceBack(){
    for(int i=1;i<=m;i++){
        if(dis_s[x[i]]+dis_t[y[i]]+t[i] == dis_s[n]){
            addedge(x[i],y[i],c[i]);
            addedge(y[i],x[i],0);
        }
        if(dis_t[x[i]]+dis_s[y[i]]+t[i] == dis_s[n]){
            addedge(y[i],x[i],c[i]);
            addedge(x[i],y[i],0);
        }
    }
}
bool bfs(){
    for(int k=1;k<=n;k++) d[k] = 0;
    queueq;q.push(S);
    d[S] = 1;
    while(!q.empty()){
        int u = q.front();q.pop();
        for(int i=head[u];i;i=edge[i].next){
            int e = edge[i].e;
            if(d[e] || edge[i].w <=0) continue;
            d[e] = d[u]+1;
            q.push(e);
        }
    }
    for(int i=0;i<=n;i++) cur[i] = head[i];///now
    return (d[T]!=0);
}
ll dfs(int u,ll flow){///
    if(u == T) return flow;
    for(int i=cur[u];i;i=edge[i].next){
        cur[u] = i;
        int e = edge[i].e;
        if(d[e] != d[u]+1||edge[i].w<=0) continue;
        ll temp = dfs(e,min(flow,edge[i].w));
        if(temp<=0) continue;
        edge[i].w -= temp;
        edge[i^1].w += temp;
        return temp;
    }
    return 0;
}
ll dinic(){
    ll maxflow = 0,delta = 0;
    while(bfs()){
        while(delta = dfs(S,INF)) maxflow += delta;
    }return maxflow;
}
int main()
{
    read(n);read(m);
    S = 1,T = n;
    for(int i=1;i<=m;i++){
        read(x[i]);read(y[i]);read(t[i]);read(c[i]);
        v[x[i]].push_back({y[i],i});
        v[y[i]].push_back({x[i],i});
    }
    spfa(1,dis_s);
    spfa(n,dis_t);
    printf("%lld\n",dis_s[n]);
    TraceBack();
    printf("%lld\n",dinic());
    return 0;
}

 

你可能感兴趣的:(网络流,最短路)