bzoj2561: 最小生成树

来源:互联网 发布:新兴重工查知的老婆 编辑:程序博客网 时间:2024/06/05 17:55

挺好的一道题。。
因为要是他连通的两个点有别的方式连通比他优的话,他就不会被选到
所以把比他优的边放到图里,跑最大流就好了。。
一开始还开了单向边WA了几发。。

#include<cstdio>#include<algorithm>#include<queue>#include<iostream>#include<cstring>using namespace std;const int N=20005;const int M=200005*2;int n,m;struct qq{    int x,y,z,last;    bool operator < (const qq &a) const {return z<a.z;}}a[M],s[M];int num,last[N];void init (int x,int y,int z){    num++;    s[num].x=x;s[num].y=y;s[num].z=z;    s[num].last=last[x];    last[x]=num;}int ans=0;int X,Y,Z;int h[N];bool bt (){    memset(h,-1,sizeof(h));h[X]=1;    queue<int> q;    q.push(X);    while (!q.empty())    {        int x=q.front();q.pop();        for (int u=last[x];u!=-1;u=s[u].last)        {            int y=s[u].y;            if (s[u].z>0&&h[y]==-1)            {                h[y]=h[x]+1;                q.push(y);            }        }    }    return h[Y]!=-1;}int mymin (int x,int y){return x<y?x:y;}int dfs (int x,int f){    if (x==Y) return f;    int s1=0;    for (int u=last[x];u!=-1;u=s[u].last)    {        int y=s[u].y;        if (s[u].z>0&&h[y]==h[x]+1&&s1<f)        {            int lalal=dfs(y,mymin(s[u].z,f-s1));            s1+=lalal;            s[u].z-=lalal;            s[u^1].z+=lalal;        }    }    if (s1==0) h[x]=-1;    return s1;}int main(){    scanf("%d%d",&n,&m);    for (int u=1;u<=m;u++)  scanf("%d%d%d",&a[u].x,&a[u].y,&a[u].z);    sort(a+1,a+1+m);    scanf("%d%d%d",&X,&Y,&Z);    num=1;memset(last,-1,sizeof(last));    for (int u=1;u<=m;u++)    {        if (a[u].z>=Z) break;        init(a[u].x,a[u].y,1);        init(a[u].y,a[u].x,1);    }    while (bt()==true) ans=ans+dfs(X,1<<30);    num=1;memset(last,-1,sizeof(last));    for (int u=m;u>=1;u--)    {        if (a[u].z<=Z) break;        init(a[u].x,a[u].y,1);        init(a[u].y,a[u].x,1);    }    while (bt()==true) ans=ans+dfs(X,1<<30);    printf("%d\n",ans);    return 0;}