4215.與機關的決戰

Description

Lab與機關SERN展開了最後決戰。

SERN派出了兇惡的FB,而Labmem們要捕獲FB。FB剛剛在第三水車廠露過行蹤,Lab首領岡倫決定傾Lab之力全力追捕FB。

抓捕發生的地點可以表示成一張無向帶權圖,第三水車廠位於節點1。

岡倫仔細研究了FB的行爲模式後得出以下結論:

首先,FB擁有極強的反跟蹤能力,因此他深知不走回頭路的重要性。他永遠不會訪問任何一個節點兩次。

其次,FB行動以“速”著稱,所以FB總是走最短路。亦即,FB訪問任何一個節點時,走的路線都是從第三水車廠到該節點的最短路。這裏保證從第三水車廠(節點1)到任意節點的最短路唯一。

第三,FB處於不停運動之中。亦即,只要有相鄰的節點能滿足前兩條,他必然會移動。若有多個相鄰節點可供選擇,他會隨機等概率選擇一個作爲他的移動目標。若沒有節點滿足這一要求,那麼FB會跳世界線。而一旦FB跳世界線,Lab的這次行動很顯然就意味着徹底失敗。

岡倫分析出以上結論後決定,只能在節點上佈置Labmem,實施埋伏抓捕。但是,FB的身體素質、格鬥技術都十分優秀。因此,即使FB中伏,也有一定概率逃脫。當然,隨着在此地埋伏的Labmem的數目的增多,逃脫機率會減小。如果逃脫成功,FB會像什麼都沒發生一樣,繼續按上文所述的原則行動。
注意,FB一旦到達某個節點,埋伏在該處的Labmem會立即行動,只有FB逃脫了當前節點的抓捕後才能進行下一步行動(繼續移動或跳世界線),包括節點1,也就是說FB需要先逃脫節點1的埋伏才能進行他的第一次行動。

現在岡倫已經知道各節點設置不同數量的Labmem能成功抓捕FB的概率,現在岡倫想要使得抓捕成功的概率最大。

Input

輸入文件第一行包含兩個數N,M,分別表示節點數和邊數。
接下來M行,每行3個數u,v,w,表示節點u和v之間有一條權值爲w的無向邊。
接下來一個數S,表示可以參與埋伏的Labmem成員總數。
接下來N行,每行S個數,第i行第j個數Pij表示在節點i埋伏j個Labmem抓捕成功的概率。注意,如果不埋伏任何Labmem,那麼顯然絕不可能捕獲FB。

Output

輸出文件僅包含一個實數,保留4位小數,表示最大捕獲概率。

Data Constraint

對於20%的數據,N,S<=6
對於50%的數據,N,S<=30,每個節點度數不大於3
對於100%的數據,N,S<=200,M<=20000,1<=a,b<=N,1<=c<=10000,
0<Pij<=1
無自環、無重邊

Code

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
const int N=210;
int a[N][N],b[N][N],n,m;
double f[N][N],p[N][N],g[N][N];
int fa[N],num[N],son[N][N],s,d[N],top,tail;
int main()
{
	scanf("%d%d",&n,&m);
	fo(i,1,m)
	{
		int u,v,w;
		scanf("%d%d%d",&u,&v,&w);
		a[u][v]=a[v][u]=b[u][v]=b[v][u]=w;
	}
	fo(i,1,n)
		fo(j,1,n)
			if (i!=j)
				fo(k,1,n)
					if (i!=k && j!=k && b[j][i] && b[i][k])
						if (b[j][k]==0 || b[j][i]+b[i][k]<b[j][k]) 
							b[j][k]=b[j][i]+b[i][k];
	fo(i,1,n)
		fo(j,1,n)
			if (i!=j)
				if (a[i][j] && b[1][i]+a[i][j]==b[1][j]) 
					fa[j]=i,num[i]++,son[i][++son[i][0]]=j;
	scanf("%d",&s);
	fo(i,1,n) 
		fo(j,1,s) 
			scanf("%lf",&p[i][j]);
	top=0,tail=0;
	fo(i,1,n)
		if (num[i]==0) 
			d[++tail]=i;
	while (top<tail)
	{
		int x=d[++top];
		if (son[x][0]==0)
		{
			fo(i,1,s) 
				f[x][i]=p[x][i];
		} 
		else
		{
			memset(g,0,sizeof(g));
			fo(i,1,s) 
				g[1][i]=f[son[x][1]][i];
			fo(i,2,son[x][0])
			    fo(j,0,s)
			    	fo(k,0,j)
			    		g[i][j]=max(g[i][j],g[i-1][k]+f[son[x][i]][j-k]);
			fo(i,1,s) 
				g[son[x][0]][i]/=son[x][0]+0.0;
			fo(i,1,s)
			   fo(j,0,i)
			  		f[x][i]=max(f[x][i],p[x][j]+(1-p[x][j])*g[son[x][0]][i-j]);
		}
		num[fa[x]]--;
		if (num[fa[x]]==0) 
			d[++tail]=fa[x];
	}
	printf("%.4lf",f[1][s]);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章