1. 程式人生 > >【BZOJ3143】[Hnoi2013]遊走 期望DP+高斯消元

【BZOJ3143】[Hnoi2013]遊走 期望DP+高斯消元

結束 strong 思路 add tin clu long family continue

【BZOJ3143】[Hnoi2013]遊走

Description

一個無向連通圖,頂點從1編號到N,邊從1編號到M。
小Z在該圖上進行隨機遊走,初始時小Z在1號頂點,每一步小Z以相等的概率隨機選 擇當前頂點的某條邊,沿著這條邊走到下一個頂點,獲得等於這條邊的編號的分數。當小Z 到達N號頂點時遊走結束,總分為所有獲得的分數之和。
現在,請你對這M條邊進行編號,使得小Z獲得的總分的期望值最小。

Input

第一行是正整數N和M,分別表示該圖的頂點數 和邊數,接下來M行每行是整數u,v(1≤u,v≤N),表示頂點u與頂點v之間存在一條邊。 輸入保證30%的數據滿足N≤10,100%的數據滿足2≤N≤500且是一個無向簡單連通圖。

Output

僅包含一個實數,表示最小的期望值,保留3位小數。

Sample Input

3 3
2 3
1 2
1 3

Sample Output

3.333

HINT

邊(1,2)編號為1,邊(1,3)編號2,邊(2,3)編號為3。

題解:一個清晰的思路:我們如果能求出每條邊期望被經過的次數,然後排個序,讓期望次數越大的邊的編號越小就行了。但是問題來了,點數500,邊數?????,以邊為變量跑高斯消元顯然會TLE,那麽我們只能以點為變量跑高斯消元。那麽如何用點的期望表示邊的期望呢?其實很簡單,設邊(a,b),點a的期望被經過次數是f[a],點b的是f[b],a的度數是d[a],b的是d[b],那麽這條邊的期望被經過次數顯然是${f[a]\over d[a]}+{f[b]\over d[b]}$。

然後就是老辦法了,如果存在邊(a,b),那就f[a]+=f[b]/d[b],處理出來再移項即可,直接上高斯消元。

別忘了f[n]=1,f[1]要+1(因為是起始點)

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long double ld;
int n,m;
int pa[130000],pb[130000],d[510];
ld pc[130000],v[510][510],ans;
void add(int a,int b)
{
	if(a==n)	return ;
	v[b][a]-=(ld)1/d[a];
}
int main()
{
	scanf("%d%d",&n,&m);
	int i,j,k;
	for(i=1;i<=m;i++)	scanf("%d%d",&pa[i],&pb[i]),d[pa[i]]++,d[pb[i]]++;
	for(i=1;i<=m;i++)	add(pa[i],pb[i]),add(pb[i],pa[i]);
	for(i=1;i<=n;i++)	v[i][i]+=1;
	for(i=1;i<=n+1;i++)	v[n][i]=0;
	v[n][n]=v[n][n+1]=1,v[1][n+1]+=1;
	for(i=1;i<=n;i++)
	{
		for(j=i+1;j<=n;j++)	if(fabs(v[j][i])>fabs(v[i][i]))	for(k=i;k<=n+1;k++)	swap(v[i][k],v[j][k]);
		if(fabs(v[i][i])<1e-7)	continue;
		for(j=n+1;j>=i;j--)	v[i][j]/=v[i][i];
		for(j=1;j<=n;j++)	if(i!=j)
		{
			for(k=1;k<=n+1;k++)	if(i!=k)	v[j][k]-=v[j][i]*v[i][k];
			v[j][i]=0;
		}
	}
	for(i=1;i<=m;i++)
	{
		if(pa[i]!=n&&fabs(v[pa[i]][pa[i]])>1e-7)	pc[i]+=v[pa[i]][n+1]/d[pa[i]];
		if(pb[i]!=n&&fabs(v[pb[i]][pb[i]])>1e-7)	pc[i]+=v[pb[i]][n+1]/d[pb[i]];
	}
	sort(pc+1,pc+m+1);
	for(i=1;i<=m;i++)	ans+=(m-i+1)*pc[i];
	printf("%.3lf",(double)ans);
	return 0;
}

【BZOJ3143】[Hnoi2013]遊走 期望DP+高斯消元