• BZOJ 2521 最小生成树(最小割)


    http://www.lydsy.com/JudgeOnline/problem.php?id=2521

    题意:每次能增加一条边的权值1,求最小代价让一条边保证在最小生成树里

    思路:如果两个点中有环,那么这条边必须不能是环的最大边,这样子把之前所有的边权值变成V+1-v[i],无向图网络流就可以了

     1 #include<algorithm>
     2 #include<cstdio>
     3 #include<cmath>
     4 #include<cstring>
     5 #include<iostream>
     6 #define inf 0x7fffffff
     7 struct edge{
     8     int u,v,w;
     9 }e[200005];
    10 int n,m,id,dis[200005],cnt[200005],tot,S,T,nodes;
    11 int flow[200005],op[200005],next[200005],first[200005],go[200005];
    12 int read(){
    13     char ch=getchar();int t=0,f=1;
    14     while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
    15     while ('0'<=ch&&ch<='9'){t=t*10+ch-'0';ch=getchar();}
    16     return t*f;
    17 }
    18 void insert(int x,int y,int z){
    19     tot++;
    20     go[tot]=y;
    21     next[tot]=first[x];
    22     first[x]=tot;
    23     flow[tot]=z;
    24 }
    25 void add(int x,int y,int z){
    26     insert(x,y,z);op[tot]=tot+1;
    27     insert(y,x,0);op[tot]=tot-1;
    28 }
    29 void add2(int x,int y,int z){
    30     insert(x,y,z);op[tot]=tot+1;
    31     insert(y,x,z);op[tot]=tot-1;
    32 }
    33 int dfs(int x,int f){
    34     if (x==T) return f;
    35     int mn=nodes,sum=0;
    36     for (int i=first[x];i;i=next[i]){
    37         int pur=go[i];
    38         if (flow[i]&&dis[pur]+1==dis[x]){
    39             int save=dfs(pur,std::min(f-sum,flow[i]));
    40             sum+=save;
    41             flow[i]-=save;
    42             flow[op[i]]+=save;
    43             if (sum==f||dis[S]>=nodes) return sum;
    44         }
    45         if (flow[i]) mn=std::min(mn,dis[pur]);
    46     }
    47     if (sum==0){
    48         cnt[dis[x]]--;
    49         if (cnt[dis[x]]==0){
    50             dis[S]=nodes;
    51         }else{
    52             dis[x]=mn+1;
    53             cnt[dis[x]]++;
    54         }
    55     }
    56     return sum;
    57 }
    58 int main(){
    59     n=read();m=read();id=read();
    60     S=0,T=n+1;nodes=n+2;
    61     for (int i=1;i<=m;i++){
    62         e[i].u=read();e[i].v=read();e[i].w=read();
    63     }
    64     add(S,e[id].u,inf);
    65     add(e[id].v,T,inf);
    66     for (int i=1;i<=m;i++)if (i!=id&&e[i].w<=e[id].w){
    67         add2(e[i].u,e[i].v,e[id].w+1-e[i].w);
    68     }
    69     int ans=0;
    70     while (dis[S]<nodes) ans+=dfs(S,inf);
    71     printf("%d
    ",ans); 
    72 }
  • 相关阅读:
    学期总结
    C语言II博客作业04
    C语言I博客作业08
    第十六周助教总结
    C语言||博客作业02
    期末助教总结
    S1 冒泡排序
    关于asp.net HttpUtility.UrlDecode解码问题
    asp.net Sql缓存依赖(SqlCacheDependency)
    解决aps.net 2.0中ajax调用webservice的问题
  • 原文地址:https://www.cnblogs.com/qzqzgfy/p/5581332.html
Copyright © 2020-2023  润新知