19hdu多校 第一场 Path || bzoj1266 //dijkstra+dinic

题意:给一个有重边的图,删某条边有一个代价wi,求最小的代价和,使得此图的最短路长度边长。

思路:

先处理出最短路相关的图,即保留:d[i.to]=d[now]+d[i.cost]的边。

然后在此图上求最小割(最大流。

因为处理出来的是无环图,所以dinic可以跑的飞快

https://www.lydsy.com/JudgeOnline/problem.php?id=1266

这里用bzoj。

无向图,建图双向判断。

 

/**************************************************************
    Problem: 1266
    User: rshs
    Language: C++
    Result: Accepted
    Time:868 ms
    Memory:24088 kb
****************************************************************/
 
#include
using namespace std;
#define int long long
#define LL long long
#define FI first
#define SE second
#define MP make_pair
#define PII pair
const int mod = 1e9+7;
const int MX = 2e5+5;
 
LL d[MX];int vis[MX];
 
struct No{LL co,to;};
bool  operator<(const No &x,const No &y){return x.co>y.co;}
vectorog[MX];
 
struct no{LL to,cap,rev;}; //arc
vectorg[MX]; //图
LL level[MX]; //到起点的距离
LL iter[MX]; //当前弧,在其之前的边已经没用了
void addarc(int s,int e,int c){
    g[s].push_back((no){e,c,g[e].size()});
    g[e].push_back((no){s,0,g[s].size()-1});
}
 
LL aa[MX],bb[MX],cc[MX],dd[MX];
 
//更新层次,即level
void bfs(int s){
    memset(level,-1,sizeof(level));
    level[s]=0;
    queueq;
    q.push(s);
    while(!q.empty()){
        int now=q.front();q.pop();
        for(int i=0;i<(int)g[now].size();i++){
            no &arc=g[now][i];
            if(level[arc.to]!=-1||arc.cap<=0) continue;
            level[arc.to]=level[now]+1;
            q.push(arc.to);
        }
    }
}
//寻找增广路
LL dfs(int v,int t,LL f){
    if(v==t) return f;
    for(iter[v];iter[v]<(int)g[v].size();iter[v]++){
        no &arc=g[v][iter[v]];
        if(arc.cap<=0||level[arc.to]!=level[v]+1) continue;
        LL d=dfs(arc.to,t,min(f,arc.cap));
        if(d>0) {
            arc.cap=arc.cap-d;
            g[arc.to][arc.rev].cap+=d;
            return d;
        }
    }
    return 0;
}
LL Dinic(int s,int t){
    LL re=0;
    while(1){
        bfs(s);
        memset(iter,0,sizeof(iter));
        if(level[t]==-1) return re;
        LL f;
        while((f=dfs(s,t,LLONG_MAX))>0)
            re=re+f;
    }
    return re;
}
mapma;
signed main(){
 
        int n,m;cin>>n>>m;ma.clear();
        for(int i=1;i<=n;i++)d[i]=LLONG_MAX/2,vis[i]=0,og[i].clear(),g[i].clear();
        for(int i=1;i<=m;i++){
            cin>>aa[i]>>bb[i]>>cc[i]>>dd[i];
            og[aa[i]].push_back(No{cc[i],bb[i]});
            og[bb[i]].push_back(No{cc[i],aa[i]});
        }
        priority_queueq;d[1]=0;q.push(No{0,1});
        while(!q.empty()){
            int now=q.top().to;q.pop();
            if(vis[now])continue;
            vis[now]=1;
            for(int i=0;i<(int)og[now].size();i++){
                if(og[now][i].co+d[now]

 

你可能感兴趣的:(图,网络流)