[HNOI2013]遊走
阿新 • • 發佈:2017-10-24
dcm -- style 一行 pre n-1 noi cstring 表示
輸出格式:
題目描述
一個無向連通圖,頂點從1編號到N,邊從1編號到M。 小Z在該圖上進行隨機遊走,初始時小Z在1號頂點,每一步小Z以相等的概率隨機選 擇當前頂點的某條邊,沿著這條邊走到下一個頂點,獲得等於這條邊的編號的分數。當小Z 到達N號頂點時遊走結束,總分為所有獲得的分數之和。 現在,請你對這M條邊進行編號,使得小Z獲得的總分的期望值最小。
輸入輸出格式
輸入格式:第一行是正整數N和M,分別表示該圖的頂點數 和邊數,接下來M行每行是整數u,v(1<=u,v<=N),表示頂點u與頂點v之間存在一條邊。 輸入保證30%的數據滿足N<=10,100%的數據滿足2<=N<=500且是一個無向簡單連通圖。
僅包含一個實數,表示最小的期望值,保留3位小數。
輸入輸出樣例
輸入樣例#1: 復制3 3 2 3 1 2 1 3輸出樣例#1: 復制
3.333
說明
邊(1,2)編號為1,邊(1,3)編號2,邊(2,3)編號為3。
算出每條邊的期望走過次數
貪心,期望大的給小編號,答案最小
每條邊的期望走過次數可以由兩個端點的期望次數算出來
E[i]=e[u]/d[u]+e[v]/d[v]
那麽問題就轉為求點期望走過次數
對於每一個點u
我們有e[u]=∑(e[v]/d[v])
特例:
1是起點,期望步數+1
n是終點,期望為0
於是列出n-1個方程,高斯消元
此代碼在洛谷玄學WA,但BZOJ能AC
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 using namespace std; 7 struct link 8 { 9 int u,v; 10 }Link[500101]; 11 struct Node 12 { 13 int next,to;14 }edge[500101]; 15 int head[601],num,n,m; 16 double a[601][601],ans[601],d[601],E[500101],anss; 17 void add(int u,int v) 18 { 19 num++; 20 edge[num].next=head[u]; 21 head[u]=num; 22 edge[num].to=v; 23 } 24 const double eps=1e-12; 25 int dcmp(double x) 26 { 27 if (x<=eps&&x>=-eps) return 0; 28 return (x>0)?1:-1; 29 } 30 void gauss() 31 {int i,now,j,k; 32 for (i=1;i<=n;i++) 33 { 34 now=i; 35 for (j=i+1;j<=n;j++) 36 if (dcmp(a[now][i]-a[j][i])<0) 37 now=j; 38 if (now!=i) 39 for (j=i;j<=n+1;j++) 40 swap(a[now][j],a[i][j]); 41 for (j=i+1;j<=n;j++) 42 if (dcmp(a[j][i])) 43 { 44 double t=a[j][i]/a[i][i]; 45 for (k=i+1;k<=n+1;k++) 46 a[j][k]-=a[i][k]*t; 47 } 48 } 49 for (i=n;i>=1;i--) 50 { 51 for (j=i+1;j<=n;j++) 52 { 53 a[i][n+1]-=a[i][j]*ans[j]; 54 } 55 ans[i]=a[i][n+1]/a[i][i]; 56 } 57 } 58 int main() 59 {int i,u,v,j; 60 cin>>n>>m; 61 for (i=1;i<=m;i++) 62 { 63 scanf("%d%d",&u,&v); 64 add(u,v);add(v,u); 65 Link[i].u=u;Link[i].v=v; 66 d[u]+=1.0;d[v]+=1.0; 67 } 68 a[1][n]=-1.0; 69 for (i=1;i<n;i++) 70 a[i][i]=-1.0; 71 for (i=1;i<n;i++) 72 { 73 for (j=head[i];j;j=edge[j].next) 74 { 75 int v=edge[j].to; 76 if (v!=n) 77 { 78 a[i][v]=1.0/d[v]; 79 } 80 } 81 } 82 n--; 83 gauss(); 84 for (i=1;i<=m;i++) 85 E[i]=ans[Link[i].u]/d[Link[i].u]+ans[Link[i].v]/d[Link[i].v]; 86 sort(E+1,E+m+1); 87 for (i=1;i<=m;i++) 88 anss+=E[i]*(m-i+1.0); 89 printf("%.3lf\n",anss); 90 }
[HNOI2013]遊走