zoukankan      html  css  js  c++  java
  • 【COGS 1873】 [国家集训队2011]happiness(吴确)

    传送门 http://cojs.tk/cogs/problem/problem.php?pid=1873
    开始建图偷懒重边没有合并 结果TLE了一半!!!
    这个题解一搜一大片! 和我做的上一个网络流类似!!

    在这个OJ上面是要写文件的!

    我的Add()里面的合并并不是可有可无的 没有又会TLE.....

    dfs()里面的f判断是必须的 以前Poj上面的几个网络流题没有也轻松水过 但这个不行 还有 “&&flow[i]!=0”也是配套的!

    #include <cstdio>
    #include <iostream>
    #include <cstring>
    #include <algorithm>
    #include <cstdlib>
    using namespace std;
    #define MAXN 1000000
    #define INF 100000000
    int id[101][101],cnt=0;
    int S[MAXN][2],T[MAXN][2];
    int s,t,n,m;
    int tot=2,g[MAXN],num[MAXN],nnext[MAXN],flow[MAXN];
    int team[MAXN*40],head,tail;
    int d[MAXN];
    void Add(int x,int y,int z)
    {
    	for(int i=g[x];i;i=nnext[i])
    		if(num[i]==y)
    		{
    			flow[i]+=z;
    			return ;
    		}
    	nnext[tot]=g[x];g[x]=tot;num[tot]=y;flow[tot]=z;tot++;
    }
    bool bfs()
    {
    	head=tail=0;memset(d,0,sizeof(d));
    	d[s]=1;team[++tail]=s;
    	while(head<tail)
    	{
    		int x=team[++head];
    		for(int i=g[x];i;i=nnext[i])
    		{
    			int tmp=num[i];
    			if(d[tmp]==0&&flow[i]!=0)
    				d[tmp]=d[x]+1,team[++tail]=tmp;
    		}
    	}
    	if(d[t]==0) return false;
    	return true;
    }
    int dfs(int x,int mmin)
    {
    	if(x==t) return mmin;
    	int tmp,f=0;
    	for(int i=g[x];i;i=nnext[i])
    		if(d[num[i]]==d[x]+1&&flow[i]!=0&&(tmp=dfs(num[i],min(mmin,flow[i]))))
    		{
    			flow[i]-=tmp;
    			flow[i^1]+=tmp;
    			f+=tmp;mmin-=tmp;
    			if(mmin==0) return f;
    		}
    	return f;
    }
    int main()
    {
    	freopen("nt2011_happiness.in","r",stdin);
    	freopen("nt2011_happiness.out","w",stdout);
    	scanf("%d %d",&n,&m);s=0;t=n*m+1;
    	int tmp;
    	int sum=0;
    	for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) id[i][j]=++cnt;
    	for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) scanf("%d",&tmp),sum+=tmp,S[id[i][j]][0]+=tmp*2;
    	for(int i=1;i<=n;i++) for(int j=1;j<=m;j++)	scanf("%d",&tmp),sum+=tmp,T[id[i][j]][1]+=tmp*2;
    	for(int i=1;i< n;i++) for(int j=1;j<=m;j++) scanf("%d",&tmp),sum+=tmp,Add(id[i][j],id[i+1][j],tmp),Add(id[i+1][j],id[i][j],tmp),S[id[i][j]][0]+=tmp,S[id[i+1][j]][0]+=tmp;
    	for(int i=1;i< n;i++) for(int j=1;j<=m;j++) scanf("%d",&tmp),sum+=tmp,Add(id[i][j],id[i+1][j],tmp),Add(id[i+1][j],id[i][j],tmp),T[id[i][j]][1]+=tmp,T[id[i+1][j]][1]+=tmp;
    	for(int i=1;i<=n;i++) for(int j=1;j< m;j++) scanf("%d",&tmp),sum+=tmp,Add(id[i][j],id[i][j+1],tmp),Add(id[i][j+1],id[i][j],tmp),S[id[i][j]][0]+=tmp,S[id[i][j+1]][0]+=tmp;
    	for(int i=1;i<=n;i++) for(int j=1;j< m;j++) scanf("%d",&tmp),sum+=tmp,Add(id[i][j],id[i][j+1],tmp),Add(id[i][j+1],id[i][j],tmp),T[id[i][j]][1]+=tmp,T[id[i][j+1]][1]+=tmp;
    	for(int i=1;i<=cnt;i++) Add(s,i,S[i][0]),Add(i,s,S[i][1]);
    	for(int i=1;i<=cnt;i++) Add(t,i,T[i][0]),Add(i,t,T[i][1]);
    	int ans=0;
    	while(bfs()) ans+=dfs(s,INF);
    	printf("%d\n",sum-ans/2);
    	return 0;
    }
    
  • 相关阅读:
    显示器面板参数
    解决SQL Server 2008安装时提示:重新启动计算机 失败
    SQL Server 的 TSQL 语句的性能评估方法
    判断字母大小写
    linux发展史简介
    下载route命令源码
    TCP糊涂窗口综合症
    QT显示中文
    TCP四个定时器 之 TCP坚持定时器
    android 去ListView滑动阴影
  • 原文地址:https://www.cnblogs.com/ofsxb/p/5108987.html
Copyright © 2011-2022 走看看