zoukankan      html  css  js  c++  java
  • POJ2594 Treasure Exploration

    题目链接:戳我
    传递闭包+DAG最小覆盖路径。
    读完题目之后发现求的路径是可以相交的,也就是说一个点可以重复经过。
    但是我们的网络流求最小覆盖路径是不能重复经过一个点的怎么办,那么那些不相交路径上的点怎么抵达呢?
    这里我们可以做个转化,先用floyd求个传递闭包,预处理出来每个点可以到达的点,然后之后连边的话如果可以到达就连边(因为它可以经过一些已经经过的点到达那些不在相交路径上的点,所以就相当于直接过去了嘛)
    代码如下(跟网上dalao的对比了下感觉自己写的好长。。。。。但是感觉。。。还是比较清晰的):

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #define MAXN 2000010
    #define S 0
    #define T 2*n+1
    using namespace std;
    int n,m,t=1;
    int head[MAXN],cur[MAXN],dis[MAXN],c[1010][1010];
    struct Edge{int nxt,to,dis;}edge[MAXN<<1];
    inline void add(int from,int to,int dis)
    {
        edge[++t].nxt=head[from],edge[t].to=to,edge[t].dis=dis,head[from]=t;
        edge[++t].nxt=head[to],edge[t].to=from,edge[t].dis=0,head[to]=t;
    }
    inline bool bfs()
    {
        queue<int>q;
        memset(dis,0x3f,sizeof(dis));
        memcpy(cur,head,sizeof(head));
        q.push(S);dis[S]=0;
        while(!q.empty())
        {
            int u=q.front();q.pop();
            for(int i=head[u];i;i=edge[i].nxt)
            {
                int v=edge[i].to;
                if(edge[i].dis&&dis[v]==0x3f3f3f3f)
                    q.push(v),dis[v]=dis[u]+1;
            }
        }
        if(dis[T]==0x3f3f3f3f) return false;
        return true;
    }
    inline int dfs(int x,int f)
    {
        if(!f||x==T) return f;
        int used=0,w;
        for(int i=cur[x];i;i=edge[i].nxt)
        {
            int v=edge[i].to;
            cur[x]=i;
            if(dis[v]==dis[x]+1&&(w=dfs(v,min(f,edge[i].dis))))
            {
                edge[i].dis-=w,edge[i^1].dis+=w;
                used+=w,f-=w;
            }
        }
        return used;
    }
    inline int dinic()
    {
        int cur_ans=0;
        while(bfs()) cur_ans+=dfs(S,(int)1e9);
        return cur_ans;
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(;;)
        {
            if(n==0&&m==0) break;
            memset(c,0,sizeof(c));
            memset(head,0,sizeof(head));
            t=1;
            for(int i=1;i<=m;i++)
            {
                int u,v;
                scanf("%d%d",&u,&v);
                c[u][v]=1;
            }
            for(int i=1;i<=n;i++)
                for(int j=1;j<=n;j++)
                    for(int k=1;k<=n;k++)
                        if(c[i][k]&&c[k][j])
                            c[i][j]=1;
            for(int i=1;i<=n;i++)
                for(int j=1;j<=n;j++)
                    if(c[i][j])
                        add(i,j+n,1);
            for(int i=1;i<=n;i++) add(S,i,1),add(i+n,T,1);
            printf("%d
    ",n-dinic());
            scanf("%d%d",&n,&m);
        }
        return 0;
    }
    
  • 相关阅读:
    27 Spring Cloud Feign整合Hystrix实现容错处理
    26 Spring Cloud使用Hystrix实现容错处理
    25 Spring Cloud Hystrix缓存与合并请求
    24 Spring Cloud Hystrix资源隔离策略(线程、信号量)
    23 Spring Cloud Hystrix(熔断器)介绍及使用
    22 Spring Cloud Feign的自定义配置及使用
    21 Spring Cloud使用Feign调用服务接口
    20 Spring Cloud Ribbon配置详解
    19 Spring Cloud Ribbon自定义负载均衡策略
    18 Spring Cloud Ribbon负载均衡策略介绍
  • 原文地址:https://www.cnblogs.com/fengxunling/p/10297274.html
Copyright © 2011-2022 走看看