【NOI2009]ゾンビ

シーケンス

私は恐れていないクレイジーです

テキスト

この質問は私を3時間かかりました。実際には、アイデアが思考のようになっているが、残念ながら、私は考えています。

実際には、最初に、私はこの問題の方法にし、貪欲DPしたかったが、理由は非常に不思議な植物の保護の範囲の、私は最後の試行を置くので、グラフ理論の上に置かれ

最初は、実際には、私が側を構築する方法がわかりません、

ので、ゾンビはステップ攻撃でステップ実行することができます

  • ビルドの背面側の各ラインの手前から、サイドを構築し、それがいずれかを表し、プロテクトの関係を

その後、植物の範囲攻撃

  • 保護された人への建設側から人々を守るために、サイドを構築し、いずれかを表しプロテクトの関係を

ここでは、なお、Bを表す保護されたBを

あなたが使用できる場合、私は思っtarjanまたはトポリングを追求するために、これらの植物は無敵である、と考えられていません。

もちろん、トポは、リスト上の程度を考慮した場合、しかし、私は仕上げたいトポ、その後I無力を。Zabanは、サラダ、ありません、休暇(選択トポ理由は、より少量のコードということで、トポ実際には、より速く、当然のTOPOより重要な利点があります)

そして、私の考えでは、我々は好きですしているTOPO、しかし、その決定が最適でない下部の後に放棄しました。木かどうかもう一度考えてDPとして、(名詞を言っている)CF467Dが、それはまた、そのタイトル走ったTarjanは、状態の発見後に明確に定義されていないことができますが、そう。クール。

私はほとんど暴力的な、オープンなアイデアを書くつもり、アルゴリズムのグラフ理論をあきらめました。

次のように暴力の考え方は次のとおりです。

  • 列挙プロセスはゾンビを置きます
  • 終了条件は、ゾンビを入れる方法はありません
  • 注:これは、バックトラックアルゴリズムです!
  • 時間計算量は\(O(2 ^ {M} ^ {NM})\)、HA

崩壊、崩壊!

心の操作広げを果たしていませんでした、私はまた、暴力の良い印象を追加しました。私は、グラフ理論に戻ります

PS:私は今の私という注意がある逆の描画操作です\(\ forallは(U、V )\ E \)であり、Vによってuの保護

我々はポイントを選出した場合、私はキャッチして、それから、私は、その後継者を選出しなければならないことを知っているトポ崩壊後、空想を。

私はアルゴリズムがラベル開かれた最大流量を、?黒疑問符、最大の閉じ部分グラフ、聞いたことがありません。Iだから、Baiduのその後を見て下最大の閉じ部分グラフのいくつかの記事、本当に突然光が参照してください!

このアルゴリズムは、ちょうど私の問題を解決することができ、私たちはその後、$ \ FORALL U \ Vに「出会うカウンターマップ、構築する必要があります\(と\そこ)(U、v)は\ E $に確かに持っている$をV \(コールが閉じられている理由である)自然のE $で

コード提供

/* make by ltao */
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <deque>
#include <stack>
#include <vector>
#include <set>
#include <list>
#include <map>
#include <time.h>
#include <fstream>
typedef unsigned long long ull;
typedef double db;
typedef long long ll;
#define fake int
#define sz 666666
#define inf sz
#define get() getchar()
using namespace std;
string read_str(){
	string x;
	char ch=get();
	while(ch=='\r'||ch=='\n'||ch==' ') ch=get();
	while(ch!='\r'&&ch=='\n'&&ch!=' ')x+=ch,ch=get();
	return x;
}
char read_ch(){
	char ch=get();
	while(ch=='\r'||ch=='\n'||ch==' ') ch=get();
	return ch;
}
int read(){
	int x=0;bool f=0;
	char ch=get();
	while(ch<'0'||ch>'9'){
		if(ch=='-') f=1;
		ch=get();
	}
	while(ch<='9'&&ch>='0'){
		x=(x<<1)+(x<<3)+(ch-'0');
		ch=get(); 
	}
	return f?-x:x;
}
const int Maxm=2*1e5+11,Maxn=2002;
int n,m,s,t,h[Maxn],cnt,maxflow,sco[Maxn],w,x,y,in[Maxn],sum,dep[Maxn],cur[Maxn];
bool can[Maxn];
struct Edge{
	int fr,to,lac,flow;
	void insert(int x,int y,int z){
		fr=x;to=y;
		lac=h[x];
		h[x]=cnt++;
		flow=z;
	}
}edge[Maxm],vedge[Maxm];

bool bfs(int s,int t){
	memset(dep,-1,sizeof dep);
	memcpy(cur,h,sizeof cur);
	queue<int> q;
	q.push(s);dep[s]=0;
	while(!q.empty()){
		int fr=q.front();
		q.pop();
		for(int i=h[fr];i!=-1;i=edge[i].lac){
			int to=edge[i].to;
			if(!edge[i].flow||dep[to]!=-1) continue;
			dep[to]=dep[fr]+1;
			q.push(to);
			if(to==t){
				while(!q.empty()) q.pop();
				return 1;
			}
		} 
	}
	return 0;
}
int dfs(int u,int min1){
	if(u==t) return min1;
	int sum=min1;
	for(int i=cur[u];i!=-1;i=edge[i].lac){
		int to=edge[i].to;
		if(!edge[i].flow||dep[to]!=dep[u]+1) continue;
		int ret=dfs(to,min(sum,edge[i].flow));
		cur[u]=i;
		edge[i].flow-=ret,edge[i^1].flow+=ret,sum-=ret;
		if(sum==0) break;
	}
	return min1-sum;
}
void Dinic(int s,int t){
	while(bfs(s,t)) 
		maxflow+=dfs(s,0x3f3f3f3f);
}
int main() {
	n=read();m=read();s=0;t=n*m+1;
	memset(h,-1,sizeof h);
	for(int i=1;i<=n*m;i++){
		sco[i]=read();
		w=read();
		while(w--){
			x=read();y=read();
			edge[cnt].insert(i,x*m+y+1,0);
			in[x*m+y+1]++;
		}
		//做他保护的 
		if(i%m!=1){
			edge[cnt].insert(i,i-1,0);
			in[i-1]++;
		}
		//连接之前的 
	}
	//topo
	queue <int> q;
	for(int i=m;i<=n*m;i+=m)
		if(in[i]==0){
			q.push(i);
		}
	while(!q.empty()){
		int fr=q.front();q.pop();
		can[fr]=1;
		for(int i=h[fr];i!=-1;i=edge[i].lac){
			int to=edge[i].to;
			in[to]--;
			if(!in[to]) q.push(to);
		}
	}
	//做topo
	int vcnt=cnt;cnt=0;
	memset(h,-1,sizeof h);
	memcpy(vedge,edge,sizeof vedge); 
	for(int i=0;i<vcnt;i++){
		int to=vedge[i].to,fr=vedge[i].fr;
		if(can[fr]&&can[to]){
			//由于最大权闭合子图 
			//我们 to 收到 fr 的保护
			//所以有 to 必有 fr
			edge[cnt].insert(to,fr,inf);
			edge[cnt].insert(fr,to,0);
		}
	}
	//连接汇点和源点 
	for(int i=1;i<=n*m;i++)
		if(can[i]){
			if(sco[i]>0){
				edge[cnt].insert(s,i,sco[i]);
				edge[cnt].insert(i,s,0);
				sum+=sco[i];
			}
			if(sco[i]<0){
				edge[cnt].insert(i,t,-sco[i]);
				edge[cnt].insert(t,i,0);
			}
		}
	Dinic(s,t);
	printf("%d",sum-maxflow);
	return 0;
}

主なアイデアは、+ Dinicトポだけで罰金

実際には、自分の感覚が何を知ることができ、そのアルゴリズムの正しさ

ロッキー

はい、私はクレイジーです

どのように私は適量とのチャ​​ットます。

一緒に彼女と一緒に、私は本当に、正常になっていません

おすすめ

転載: www.cnblogs.com/zhltao/p/12337345.html