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 无自环、无重边

Code

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

你可能感兴趣的:(信息学)