POJ3436 ACM Computer Factory(打印最大路径)

#include<iostream>
#include<queue>
#include<cstring>
#include<map>
using namespace std;
const int maxn = 100;
int p,N,s,t,n,in[maxn][maxn],flow,line;
int ans,num;
int tot,head[maxn];
map<int,int> mp;
struct Edge{
	int to,nxt,w,pw;
}e[maxn*maxn];
void add(int u,int v,int w)
{
	mp[u*maxn+v] = tot;
	e[tot].to = v; e[tot].pw = e[tot].w = w; e[tot].nxt = head[u]; head[u] = tot++; 
	e[tot].to = u; e[tot].pw = e[tot].w = 0; e[tot].nxt = head[v]; head[v] = tot++;
} 
int dep[maxn];
bool bfs()
{
	memset(dep,0,sizeof(dep));
	queue<int> q; q.push(s); dep[s] = 1;
	while(!q.empty())
	{
		int fa = q.front(); q.pop();
		for(int i = head[fa]; ~i; i = e[i].nxt)
		{
			if(e[i].w && !dep[e[i].to])
			dep[e[i].to] = dep[fa]+1, q.push(e[i].to);
		}
	}
	return dep[t];
}
int dfs(int fa,int flow)
{
	if(fa == t) return flow;
	int res = 0;
	for(int i = head[fa]; ~i; i = e[i].nxt)
	{
		int to = e[i].to , w = e[i].w;
		if(w && dep[to] == dep[fa]+1)
		{
			int d = dfs(to,min(flow,w));
			e[i].w -= d; e[i^1].w += d;
			flow -= d; res += d;
		}
	}
	if(res == 0) dep[fa] = 0;
	return res;
}
void dinic()
{
	while(bfs()) flow += dfs(s,0x3f3f3f3f);
}
int main()
{
	while(~scanf("%d%d",&p,&N))
	{
		memset(head,-1,sizeof(head)); tot = 0;
		s = 0; t = N + 1; n = N + 2;flow = 0; line = 0;
		for(int i = 1; i <= N; ++i)
		for(int j = 0; j < 2*p+1; ++j) scanf("%d",&in[i][j]);
		bool flag_s,flag_t;
		for(int i = 1; i <= N; ++i)
		{
			flag_s = flag_t = 1;
			for(int k =0; k < p; ++k)
			{
				if(in[i][k+1]==1) flag_s=false;
				if(in[i][p+1+k]==0) flag_t=false;	
			}
			if(flag_s) add(s,i,in[i][0]);
			if(flag_t) add(i,t,in[i][0]);
			bool flag = 1;
			for(int j = 1; j <= N; ++j)
			{
				if(i != j)
				{
					flag = 1;
					for(int k=0;(k<p)&&flag;++k)
					if(in[i][p+k+1]+in[j][k+1]==1) flag=false;//接口对不上不连接i和j 
					if(flag) add(i,j,min(in[i][0],in[j][0]));
				}	
			}
		} 
		dinic();
		for(int i = 1; i <= N; ++i)
		{
			for(int j = head[i]; ~j; j = e[j].nxt)
			{
				if(e[j].to == t) continue;
				int to = e[j].to, w = e[j].w;
				if(e[j].pw > e[j].w) line++;
			}
		} 
		printf("%d %d\n",flow,line);
		for(int i = 1; i <= N; ++i)
		{
			for(int j = head[i]; ~j; j = e[j].nxt)
			{
				if(e[j].to == t) continue;
				int to = e[j].to, w = e[j].w;
				if(e[j].pw > e[j].w) printf("%d %d %d\n",e[j^1].to, e[j].to,e[j].pw - e[j].w);
			}
		} 
	}
}

主要是最大路径的打印,由于网络流的特点 最大流是确定的,但是可能存在不同的到达路径,我输出的跟答案是不一样的,一直以为是算法错了,没想到是路径数量统计错了,只有当前流和之前的保存的副本不一样的时候,才路径数量+1

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值