[JZOJ4802] [探査プログラムコストの流れ]

免責事項:あなたが転載したい場合は、直接コメントで説明することができ、ありがとうございました!https://blog.csdn.net/SSL_ZYC/article/details/90727748

効果の件名:

トピックリンク:https://jzoj.net/senior/#main/show/4802を
この日には、誰もHnsdfz情報群は非常に配置することができますYuelushan Yuelu山の冒険にプレーすることを決めた、との情報グループOierをする必要があります。危険レベルを設定するすべての場所は、これが負担する危険な冒険スポットを表し、全体Yuelushanは、上部台形m個の数字があるが、各数はであることができ、n個の行番号デジタルキーストンによって抽象化することができます左上または右上動き((i、j)は(I-1、J)又は(I-1、J-1である (i、j)は、) 入力ファイル番号台形の第i行j列を示します) 。、台形の底部から頂部への経路を形成し
、誰かがあまりにも場所を歩いた場合に個性がないので最初は、誰もが感じている。
タスク1:トップに全くばらばらメートルの終わりを見つけるために。パス(繰り返さないが、それはサイド後に繰り返すことができない点を通過する)
、しかし、彼らがそのように死んで制限を感じた場合は少し考えたが、それはあまりにも退屈になりそうあります:
タスク2:デジタルのみでメートルのバーを見つけますパス交差(繰り返されてもよい点を通過したが、エッジの後に繰り返すことができない。上部に遭遇することも許可されている)
今、として全体劉 プランスポンサーは、タスク2とミッションのために計算する必要があり、ビュー、ラインを見ることができます誰もが最小限の危険を経験した。(すべての人の合計値の最小のリスクをすべての場所で取得します)


アイデア:

この質問は見て考えることですデジタルキーストン問題」 - 「24ネットワークフロー問題前に行われていないが、
これらの二つの質問のバーへの基本的な重量です。この質問は、たった2つ以外にもいくつかの大きなデータを要求され、かつ最小を求めています。
だから、ここでの考え方は、それを見るために


コード:

#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#include <queue> 
#include <cstdio>
#include <cstring>
#include <algorithm>
#define rr register
using namespace std;

const int N=20010,Inf=1e9;
int n,m,S,T,T_,cost,maxn,tot,head[N],dis[N],map[210][210],pre[N];
bool vis[N];

struct edge
{
	int next,to,from,flow,cost;
}e[N*4];

int C(int x,int y)
{
	return (m+m+x-2)*(x-1)/2+y;
}

void add(int from,int to,int flow,int cost)
{
	e[++tot].to=to;
	e[tot].from=from;
	e[tot].flow=flow;
	e[tot].cost=cost;
	e[tot].next=head[from];
	head[from]=tot;
}

bool spfa()
{
	memset(dis,0x3f3f3f3f,sizeof(dis));
	memset(vis,0,sizeof(vis));
	queue<int> q;
	q.push(S);
	dis[S]=0; vis[S]=1;
	while (q.size())
	{
		int u=q.front(),v;
		q.pop();
		vis[u]=0;
		for (rr int i=head[u];~i;i=e[i].next)
		{
			v=e[i].to;
			if (e[i].flow&&dis[v]>dis[u]+e[i].cost)
			{
				dis[v]=dis[u]+e[i].cost;
				pre[v]=i;
				if (!vis[v])
				{
					vis[v]=1;
					q.push(v);
				}
			}
		}
	}
	return dis[T]<Inf;
}

void addflow()
{
	int minflow=Inf;
	for (rr int x=T;x!=S;x=e[pre[x]].from)
		minflow=min(minflow,e[pre[x]].flow);
	for (rr int x=T;x!=S;x=e[pre[x]].from)
	{
		e[pre[x]].flow-=minflow;
		e[pre[x]^1].flow+=minflow;
	}
	cost+=dis[T]*minflow;
}

int MCMF()
{
	while (spfa())
		addflow();
	return cost;
}

void make(int val)
{
	tot=1;
	memset(head,-1,sizeof(head));
	for (rr int i=1;i<=n;i++)
		for (rr int j=1;j<=m+i-1;j++)
		{
			add(C(i,j),C(i,j)+maxn,val,map[i][j]);
			add(C(i,j)+maxn,C(i,j),0,-map[i][j]);
			if (i<n)
			{
				add(C(i,j)+maxn,C(i+1,j),1,0);
				add(C(i+1,j),C(i,j)+maxn,0,0);
				add(C(i,j)+maxn,C(i+1,j+1),1,0);
				add(C(i+1,j+1),C(i,j)+maxn,0,0);
			}
		}
	for (rr int i=1;i<=m;i++)
	{
		add(S,C(1,i),val,0);
		add(C(1,i),S,0,0);
	}
	for (rr int i=1;i<=m+n-1;i++)
	{
		add(C(n,i)+maxn,T_,val,0);
		add(T_,C(n,i)+maxn,0,0);
	}
	add(T_,T,m,0);
	add(T,T_,0,0);
	cost=0;
}

int main()
{
	scanf("%d%d",&n,&m);
	for (rr int i=1;i<=n;i++)
		for (rr int j=1;j<=m+i-1;j++)
			scanf("%d",&map[i][j]);
	S=20009; T_=20008; T=20007;
	maxn=C(n,n+m-1);
	make(1); printf("%d\n",MCMF());
	make(m); printf("%d\n",MCMF());
	return 0;
}

おすすめ

転載: blog.csdn.net/SSL_ZYC/article/details/90727748