2019EC-FINAL E题 Flow(贪心)

这题的图非常特殊,首先他没有交点,其次他每条路径的长度都是相等的,也就是每一条边都是对应的。

根据常规的贪心思路,因为他的最大流是全部路径中的流量和,并且你将一个边-1,必有另一个边+1,最大流的答案就是总容量/路径上的边数

那么其实可以想出做法了,我们已经知道的最大流是多少,所以我们将路径按权值排序,对应路径上的容量全部相加,因为每条路都会收到容量小的边的控制,所以一定要贯通这些边,使得他们的和大于最大流。

只需要判断最大流是否大于当前容量和即可。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=5e5+10;
int h[N],ne[N],e[N],w[N],idx;
vector<int> g[N];
int n,m,cnt;
void add(int a,int b,int c){
    e[idx]=b,ne[idx]=h[a],w[idx]=c,h[a]=idx++;
}
void dfs(int u,int fa){
    if(u==n)
        return ;
    int i;
    for(i=h[u];i!=-1;i=ne[i]){
        int j=e[i];
        if(j==fa)
            continue;
        g[cnt].push_back(w[i]);
        dfs(j,u);
    }
}
int main(){
    ios::sync_with_stdio(false);
    memset(h,-1,sizeof h);
    int i;
    cin>>n>>m;
    ll flow=0;
    for(i=1;i<=m;i++){
        int x,y,z;
        cin>>x>>y>>z;
        add(x,y,z);
        flow+=z;
    }
    for(i=h[1];i!=-1;i=ne[i]){
        int j=e[i];
        g[++cnt].push_back(w[i]);
        dfs(j,-1);
        sort(g[cnt].begin(),g[cnt].end());
    }
    flow/=(int)g[1].size();
    ll ans=0;
    for(i=0;i<(int)g[1].size();i++){
        ll sum=0;
        for(int j=1;j<=cnt;j++){
            sum+=g[j][i];
        }
        if(sum>=flow)
            break;
        ans+=(flow-sum);
    }
    cout<<ans<<endl;
}
View Code

 

posted @ 2020-12-12 10:19  朝暮不思  阅读(173)  评论(0编辑  收藏  举报