Loading

代码-清华集训2012 最小生成树

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
#define x first
#define y second
#define bg begin()
#define ed end()
#define pb push_back
#define mp make_pair
#define sz(a) int((a).size())
#define R(i,n) for(int i(0);i<(n);++i)
#define L(i,n) for(int i((n)-1);~i;--i)
const int iinf=0x3f3f3f3f;
const ll linf=0x3f3f3f3f3f3f3f3f;

//Data
const int N=20000,M=2e5;
int n,m,a,e0[M][3],now[3];

//Flows
int s,t;
vector<int> e[N],to;
vector<bool> fw;
void adde(int u,int v){
    e[u].pb(sz(to)),to.pb(v),fw.pb(true);
    e[v].pb(sz(to)),to.pb(u),fw.pb(false);
}
void clear(){
    R(i,n) e[i].clear();
    to.clear(),fw.clear();
}
int pre[N];
bool bfs(){
    R(i,n) pre[i]=-1;
    static queue<int> q;
    q.push(s);
    while(sz(q)){
        int u=q.front(); q.pop();
        for(int v:e[u])if(fw[v]&&!~pre[to[v]])
            pre[to[v]]=v,q.push(to[v]);
    }
    return ~pre[t];
}
int flow(){
    int res=0;
    while(bfs()){
        for(int u=t;u^s;u=to[pre[u]^1])
            fw[pre[u]]=false,fw[pre[u]^1]=true;
        res++;
    }
    return res;
}

//Main
int main(){
    ios::sync_with_stdio(0);
    cin.tie(0),cout.tie(0);
    cin>>n>>m;
    R(i,m){
        cin>>e0[i][0]>>e0[i][1]>>e0[i][2];
        --e0[i][0],--e0[i][1];
    }
    cin>>s>>t>>a,--s,--t;
    int ns=0;
    R(i,m) e0[i][2]-=a;
    clear();
    R(i,m)if(e0[i][2]>0){
        adde(e0[i][0],e0[i][1]);
        adde(e0[i][1],e0[i][0]);
    }
    ns+=flow();
    clear();
    R(i,m)if(e0[i][2]<0){
        adde(e0[i][0],e0[i][1]);
        adde(e0[i][1],e0[i][0]);
    }
    ns+=flow();
    cout<<ns<<'\n';
    return 0;
}

/*

可能出现在最小生成树上:

比 L 小的边不能连通 s 和 t

可能出现在最大生成树上:

比 L 大的边不能连通 s 和 t

很明显分开考虑即可

*/
posted @ 2020-11-14 16:27  George1123  阅读(73)  评论(0)    收藏  举报