• [bzoj1143][CTSC2008]祭祀


    题意:给定一个n个点m条边的有向无环图,你要选出最多的点,并且满足任意两点之间都不存在通路。2)输出每个点选了它之后还是否有最优解。   n<=100 m<=1000

    题解:每个点拆两个点,把每个点向它能走到点连边,然后最小割/二分图匹配。

    这题想了好久,后来想出这个模型感觉没问题.....

    第二个问貌似把每个点都强行不割跑一遍应该不会T吧.....

    #include<iostream>
    #include<cstdio>
    #include<queue>
    #include<cstring>
    #define S 0
    #define T 201 
    #define INF 2000000000
    using namespace std;
    inline int read()
    {
        int x = 0 , f = 1; char ch = getchar();
        while(ch < '0' || ch > '9'){ if(ch == '-') f = -1;  ch = getchar();}
        while(ch >= '0' && ch <= '9'){x = x * 10 + ch - '0';ch = getchar();}
        return x * f;
    }
     
    int mark[T+5];
    int head[T+5],cnt=1,n,m,ans,cc=0,thead[T+5],q[T+5],top,d[T+5];
    struct edge{
        int to,next,w;
    }e[T*T+5];
    struct tedge{
        int to,next;
    }e2[1005];
     
    inline void ins(int f,int t){e2[++cc]=(tedge){t,thead[f]};thead[f]=cc;}
    inline void ins(int f,int t,int w)
    {   
        e[++cnt]=(edge){t,head[f],w};head[f]=cnt;
        e[++cnt]=(edge){f,head[t],0};head[t]=cnt;
    }
     
    void build(int x,int from)
    {
        if(mark[x]!=from&&x!=from) ins(from,x+n,INF),mark[x]=from;
        for(int i=thead[x];i;i=e2[i].next)
            if(mark[e2[i].to]!=from)
                build(e2[i].to,from);
    }
     
    int dfs(int x,int f)
    {
        if(x==T)return f;
        int used=0;
        for(int i=head[x];i;i=e[i].next)
            if(e[i].w&&d[e[i].to]==d[x]+1)
            {
                int w=dfs(e[i].to,min(f-used,e[i].w));
                used+=w;e[i].w-=w;e[i^1].w+=w;
                if(used==f)return f;
            } 
        return used;
    }
     
    bool bfs()
    {
        memset(d,0,sizeof(d));int i,j;
        for(d[q[i=top=0]=S]=1;i<=top;++i)
            for(int j=head[q[i]];j;j=e[j].next)
                if(e[j].w&&!d[e[j].to])
                    d[q[++top]=e[j].to]=d[q[i]]+1;
        return d[T];
    }
     
    int main()
    {
        ans=n=read();m=read();
        for(int i=1;i<=m;i++)
        {
            int x=read(),y=read();
            ins(y,x);
        }   
        for(int i=1;i<=n;i++)build(i,i);
        for(int i=1;i<=n;i++)ins(S,i,1),ins(i+n,T,1);
        while(bfs())ans-=dfs(S,INF);
        cout<<ans;
        return 0;
    }
  • 相关阅读:
    异常方法测试实验
    exception测试实验(研究finally的作用)
    idea中文注释出现乱码,我靠自己解决了
    按装parallels tool的失败之路
    实验七
    实验六
    实验五
    实验四
    实验3
    html转义字符图
  • 原文地址:https://www.cnblogs.com/FallDream/p/bzoj1143.html
Copyright © 2020-2023  润新知