zoukankan      html  css  js  c++  java
  • bzoj2718 [Violet 4]毕业旅行

    Description

    Input

    Output

    最多可选多少景点

    Sample Input

    7 6
    1 2
    2 3
    5 4
    4 3
    3 6
    6 7

    Sample Output

    2

    HINT

    这题是结论题

    答案=最长反链=最小路径覆盖=n-二分图最大匹配

    先floyd处理出两点之间的联通性,然后拆点,如果A能到B则A向B'连边

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #define LL long long
    #define inf 0x7ffffff
    #define S 0
    #define T 2*n+1
    using namespace std;
    inline LL read()
    {
        LL 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;
    }
    struct edge{int to,next,v;}e[100010];
    int n,m,cnt=1,ans;
    bool go[1010][1010];
    int head[100010];
    int q[100010];
    int h[100010];
    inline void ins(int u,int v,int w)
    {
        e[++cnt].to=v;
        e[cnt].v=w;
        e[cnt].next=head[u];
        head[u]=cnt;
    }
    inline void insert(int u,int v,int w)
    {
        ins(u,v,w);
        ins(v,u,0);
    }
    inline bool bfs()
    {
        memset(h,-1,sizeof(h));
        q[1]=S;h[S]=0;int t=0,w=1;
        while (t<w)
        {
            int now=q[++t];
            for (int i=head[now];i;i=e[i].next)
              if (e[i].v&&h[e[i].to]==-1)
              {
                q[++w]=e[i].to;
                h[e[i].to]=h[now]+1;
              }
        }
        if (h[T]==-1)return 0;
        return 1;
    }
    inline int dfs(int x,int f)
    {
        if (x==T||!f)return f;
        int w,used=0;
        for (int i=head[x];i;i=e[i].next)
            if (e[i].v&&h[e[i].to]==h[x]+1)
            {
                w=dfs(e[i].to,min(f-used,e[i].v));
                e[i].v-=w;
                e[i^1].v+=w;
                used+=w;
                if (used==f)return f;
            }
        if (!used)h[x]=-1;
        return used;
    }
    inline void dinic()
    {while (bfs())ans+=dfs(S,inf);}
    int main()
    {
        n=read();m=read();
        for (int i=1;i<=m;i++)
        {
            int x=read(),y=read();
            go[x][y]=1;
        }
        for (int k=1;k<=n;k++)
        for (int i=1;i<=n;i++)
        for (int j=1;j<=n;j++)
        if (go[i][k]&&go[k][j])go[i][j]=1;
         
        for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
        if (go[i][j])insert(i,j+n,1);
         
        for (int i=1;i<=n;i++)
        insert(S,i,1),insert(i+n,T,1);
        dinic();
        printf("%d
    ",n-ans);
    }
    
    ——by zhber,转载请注明来源
  • 相关阅读:
    pktgen使用指南
    常见的网卡调优
    网络PPS测试
    网络性能测试工具qperf
    设置虚拟机静态IP
    superset填坑
    js格式化
    《你不知道的JavaScript》读书笔记(一):JS是如何查找变量的
    技术分享PPT整理(三):网页渲染流程
    技术分享PPT整理(二):C#常用类型与数据结构
  • 原文地址:https://www.cnblogs.com/zhber/p/4179482.html
Copyright © 2011-2022 走看看