• 752. [BJOI2006] 狼抓兔子


    ★★★☆   输入文件:bjrabbit.in   输出文件:bjrabbit.out   简单对比

    时间限制:1 s   内存限制:162 MB

    Description   Source: Beijing2006 [BJOI2006]

    八中OJ上本题链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1001

    现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的,而且现在的兔子还比较笨,它们只有两个窝,现在你做为狼王,面对下面这样一个网格的地形:

    左上角点为(1,1),右下角点为(N,M)(上图中N=4,M=5).有以下三种类型的道路 1:(x,y)<==>(x+1,y) 2:(x,y)<==>(x,y+1) 3:(x,y)<==>(x+1,y+1) 道路上的权值表示这条路上最多能够通过的兔子数,道路是无向的. 左上角和右下角为兔子的两个窝,开始时所有的兔子都聚集在左上角(1,1)的窝里,现在它们要跑到右下解(N,M)的窝中去,狼王开始伏击这些兔子.当然为了保险起见,如果一条道路上最多通过的兔子数为K,狼王需要安排同样数量的K只狼,才能完全封锁这条道路,你需要帮助狼王安排一个伏击方案,使得在将兔子一网打尽的前提下,参与的狼的数量要最小。因为狼还要去找喜羊羊麻烦.

    Input

    第一行为N,M.表示网格的大小,N,M均小于等于1000.接下来分三部分 第一部分共N行,每行M-1个数,表示横向道路的权值. 第二部分共N-1行,每行M个数,表示纵向道路的权值. 第三部分共N-1行,每行M-1个数,表示斜向道路的权值. 输入文件保证不超过10M

    Output

    输出一个整数,表示参与伏击的狼的最小数量.

    Sample Input

    3 4
    5 6 4
    4 3 1
    7 5 3
    5 6 7 8
    8 7 6 5
    5 5 5
    6 6 6

    Sample Output

    14

     裸地网络流没调出来

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <queue>
    
    using namespace std;
    const int N = 1e6 + 10;
    const int Maxn = 99999999;
    
    int head[N], dis[N];
    int n, m, S, T, now, w, x;
    struct Node{
    	int u, v, cap, flow, nxt;
    }E[N<<1-1];
    queue <int> Q;
    
    inline int read()
    {
        int x = 0, f = 1;
        char c = getchar();
        while(c < '0' || c > '9')
        {
            if(c == '-')
                f = -1;
            c = getchar();
        }
        while(c >= '0' && c <= '9')
        {
            x = x * 10 + c - '0';
            c = getchar();
        }
        return x * f;
    }
    
    inline void add(int u, int v, int cap)
    {
    	E[now].v = v;
    	E[now].cap = cap;
    	E[now].flow = 0;
    	E[now].nxt = head[u];
    	head[u] = now++;
    }
    
    inline bool bfs()
    {
    	for(int i = 1; i <= T; i ++)
    		dis[i] = -1;
    	dis[S] = 0;
    	Q.push(S);
    	while(!Q.empty())
    	{
    		int topp = Q.front();
    		Q.pop();
    		for(int i = head[topp]; ~ i; i = E[i].nxt)
    		{
    			if(dis[E[i].v] == -1 && E[i].cap - E[i].flow > 0)
    			{
    				dis[E[i].v] = dis[topp] + 1;
    				Q.push(E[i].v);
    			}
    		}
    	}
    	if(dis[T] == -1)
    		return 0;
    	else
    		return 1;
    }
    
    int dfs(int start,int minn)
    {
    	if(start == T /*|| minn <= 0*/)
    		return minn;
    	int ret = 0, flo;
    	for(int i = head[start]; ~ i; i = E[i].nxt)
    	{
    		if(dis[E[i].v] == dis[start] + 1 && E[i].cap - E[i].flow > 0)
    		{
    			flo = dfs(E[i].v, min(minn, E[i].cap - E[i].flow));
    			E[i].flow += flo;
    			E[i ^ 1].flow -= flo;
    			ret += flo;
    			minn -= flo;
    		}
    	}
    	return ret;
    }
    
    inline void Dinic()
    {
    	int answer = 0;
    	while(bfs())
    		answer += dfs(S, Maxn);
    	printf("%d",answer);
    }
    
    int main()
    {
    	//freopen("bjrabbit.in","r",stdin);
    	//freopen("bjrabbit.out","w",stdout);
    	n = read();
    	m = read();
    	S = 1;
    	T = n * m;
    	for(int i = 1; i <= T; i ++)
    		head[i] = -1;
    	for(int i = 1; i <= n; i ++)
    		for(int j = 1; j <= m - 1; j ++)
    		{
    			w = read();
    			x = (i - 1) * n + j + i - 1;
    			add(x, x + 1, w),
    			add(x + 1, x, 0);
    			//cout<<x<<" "<<x+1<<endl;
    		}
    	for(int i = 1; i <= n - 1; i ++)
    		for(int j = 1; j <= m ; j ++)
    		{
    			w = read();
    			x = (i - 1) * n + j + i - 1;
    			add(x, x + m, w);
    			add(x + m, x, 0);
    			//cout<<x<<" "<<x+m<<endl;
    		}
    		
    	for(int i = 1; i <= n - 1; i ++)
    		for(int j = 1; j <= m - 1; j ++)
    		{
    			w = read();
    			x = (i - 1) * n + j + i - 1;
    			add(x, x + m + 1, w);
    			add(x + m + 1, x, 0);
    			//cout<<x<<" "<<x+m+1<<endl;
    		}	
    	Dinic();
    	return 0;
    }
    /*	
    3 4
    5 6 4
    4 3 1
    7 5 3
    5 6 7 8
    8 7 6 5
    5 5 5
    6 6 6
    */
    

    对偶图最短路

    //平面图的最小割 = 对偶图的最短路 
    
    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define N 2001000
    #define inf 0x7fffffff
    
    struct Edge{
        int v,next,k;
    }edge[N<<2];
    int n,m,ans,num=0,S,T,head[N],dis[N],q[N*5];
    bool vis[N];
    
    int in()
    {
        int x=0; char ch=getchar();
        while (ch<'0' || ch>'9') ch=getchar();
        while (ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
        return x;
    }
    
    void add(int u,int v,int k)
    {
        edge[++num].v=v; edge[num].k=k;
        edge[num].next=head[u]; head[u]=num;
    }
    
    void spfa()
    {
        int h=0,t=1;
        memset(dis,127/3,sizeof(dis));
        memset(vis,0,sizeof(vis));
        dis[S]=0,vis[S]=1,q[h]=S;
        while (h<t)
    	{
            int u=q[h]; vis[u]=0; h++;
            if (h>=N*5) h=0,t=1;
            for (int i=head[u]; i; i=edge[i].next)
    		{
                int v=edge[i].v;
                if (dis[v]>dis[u]+edge[i].k)
    			{
                    dis[v]=dis[u]+edge[i].k;
                    if (!vis[v]) vis[v]=1,q[t++]=v;
                }
            }
        }
        ans=dis[T];
    }
    
    void build()
    {
        S=0,T=((n-1)*(m-1))<<1|1;
        for (int i=1; i<=n; i++)
            for (int j=1; j<m; j++)
    		{
                int x=in(),u,v;
                if (i==1) u=S,v=j;
                else if (i==n) u=((i-2)<<1|1)*(m-1)+j,v=T;
                else u=((i-2)<<1|1)*(m-1)+j,v=((i-1)<<1)*(m-1)+j;
                add(u,v,x),add(v,u,x);
            }
        for (int i=1; i<n; i++)
            for (int j=1; j<=m; j++)
    		{
                int x=in(),u,v;
                if (j==1) u=((i-1)<<1|1)*(m-1)+1,v=T;
                else if (j==m) u=S,v=((i-1)<<1|1)*(m-1);
                else u=((i-1)<<1)*(m-1)+j-1,v=((i-1)<<1|1)*(m-1)+j;
                add(u,v,x),add(v,u,x);
            }
        for (int i=1; i<n; i++)
            for (int j=1; j<m; j++)
    		{
                int x=in(),u,v;
                u=((i-1)<<1)*(m-1)+j,v=((i-1)<<1|1)*(m-1)+j;
                add(u,v,x),add(v,u,x);
            }
    }
    
    int main()
    {
    	freopen("bjrabbit.in","r",stdin);
    	freopen("bjrabbit.out","w",stdout); 
        n=in(),m=in();
    
        if (n==1 || m==1)
    	{
            if (n>m) swap(n,m);
            ans=inf;
            for (int i=1; i<m; i++)
    		{
                int x=in();
                ans=min(ans,x);
            }
            if (ans==inf) ans=0;
            printf("%d
    ",ans);
            return 0;
        }
    
        build(); spfa();
        printf("%d
    ",ans);
        return 0;
    }
    

      

  • 相关阅读:
    A debugger is already attached
    鼠标指向GridView某列显示DIV浮动列表
    天气插件的替换
    ZPL打印中文信息
    「PowerBI」使用TabularEditor进行PowerBIDeskTop模型开发最佳实践
    「PowerBI」丢弃SSDT选择TabularEditor成为你的首选建模开发工具(下)
    「PowerBI」丢弃SSDT选择TabularEditor成为你的首选建模开发工具(中)
    「PowerBI」丢弃SSDT选择TabularEditor成为你的首选建模开发工具(上)
    「Azure」数据分析师有理由爱Azure之十-使用PowerShell自动化AzureAS
    「Azure」数据分析师有理由爱Azure之九-填坑-PowerBI Pro连接Azure AS模型
  • 原文地址:https://www.cnblogs.com/lyqlyq/p/7327623.html
Copyright © 2020-2023  润新知