被dp虐哭。。。QAQ
以后有机会专攻dp吧,太难受了
开始图论专题
---------------------------------------------------------------分割线-------------------------------------------------------------
题目大意:
给你n个点(编号1~n)和m个集合,集合之内的点相互之间距离为1,若两个点通过第三个点连接,则其距离为2(如dis(a-b)=1,dis(b-c)=1,则dis(a-c)=2;),请你求出每个点到其他点的距离平均值最小值*100是多少(n<=300,m<=40000)
解答:
分析可知,这是多源最短路,又因为n<=300,所以用矩阵存图,n^3可过
首先建图。。对于每个点集,点之间连线为1,至于间接相连距离为2则不必考虑,因为对于a,b,c三点,dis(a-b)=1,dis(b-c)=1,dis(a-c)=2,dis(a-c)=dis(a-b)+dis(b,c),所以不用联系起来
然后就是直接floyd,最后对每个点到其他点距离计算sum/(n-1)即可
代码:
1 #include<iostream> 2 #include<cstdio> 3 #include<queue> 4 #include<algorithm> 5 #include<cstdio> 6 using namespace std; 7 int plat[333][333]; 8 int n,m,cnt; 9 int cows[333],avg[333]; 10 const int inf=999; 11 void add_edge(int m) 12 { 13 for(int i=1;i<=m;i++) 14 { 15 for(int j=1;j<=m;j++) 16 { 17 if(i==j) plat[cows[i]][cows[j]]=0; 18 else plat[cows[i]][cows[j]]=1; 19 } 20 } 21 } 22 int main() 23 { 24 //freopen("in.txt","r",stdin); 25 for(int i=0;i<333;i++) for(int j=0;j<333;j++) plat[i][j]=inf; 26 scanf("%d %d",&n,&m); 27 for(int i=1;i<=m;i++) 28 { 29 int N; 30 scanf("%d",&N); 31 for(int j=1;j<=N;j++) scanf("%d",&cows[j]); 32 add_edge(N); 33 } 34 for(int k=1;k<=n;k++) 35 { 36 for(int i=1;i<=n;i++) 37 { 38 for(int j=1;j<=n;j++) 39 { 40 if(plat[i][j]>plat[i][k]+plat[k][j]) 41 plat[i][j]=plat[i][k]+plat[k][j]; 42 } 43 } 44 } 45 46 int minn=9999999; 47 for(int i=1;i<=n;i++) 48 { 49 double sum=0; 50 for(int j=1;j<=n;j++) 51 { 52 //printf("%5d",plat[i][j]); 53 sum+=plat[i][j]; 54 } 55 //printf(" "); 56 //cout<<endl; 57 avg[i]=sum*100/(n-1); 58 minn=min(minn,avg[i]); 59 } 60 printf("%d",minn); 61 }