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]);
}