日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

[补档]藏宝图

發布時間:2024/4/15 编程问答 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [补档]藏宝图 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

藏寶圖

題目

codeforces472D加強版,原題傳送門:http://codeforces.com/problemset/problem/472/D 本題在原題基礎上加了一問,然而就是這一問把我搞炸了= = Czy爬上黑紅樹,到達了一個奇怪的地方…… Czy發現了一張奇怪的藏寶圖。圖上有n個點,m條無向邊。已經標出了圖中兩兩之間距離dist。但是czy知道,只有當圖剛好又是一顆樹的時候,這張藏寶圖才是真的。如果藏寶圖是真的,那么經過點x的邊的邊權平均數最大的那個x是藏著寶物的地方。請計算這是不是真的藏寶圖,如果是真的藏寶之處在哪里。

 INPUT

輸入數據第一行一個數T,表示T組數據。 對于每組數據,第一行一個n,表示藏寶圖上的點的個數。 接下來n行,每行n個數,表示兩兩節點之間的距離。

OUTPUT

輸出一行或兩行。第一行”Yes”或”No”,表示這是不是真的藏寶圖。 若是真的藏寶圖,第二行再輸出一個數,表示哪個點是藏寶之處。

SAMPLE

INPUT

2 3 0 7 9 7 0 2 9 2 0 3 0 2 7 2 0 9 7 9 0

OUTPUT

Yes 1 Yes 3

解題報告

考試時只打出了第一問,還是O(n3)的復雜度,自然爆了零= = 正解: 首先我們考慮第一問,我們有了每兩兩點之間的距離,并想辦法用其判斷這個圖是否是一棵樹,我們想,在一棵樹中,每兩點之間路徑是唯一的,故路徑長度即為路徑所經過所有邊的長度之和,那么我們利用所給距離建出最小生成樹,假如該圖為樹,那么最小生成樹即為本身,假如不是,那么兩點間距離一定會有變化,這些利用dfs什么的就可以做到了,順便還可以建成圖。 這里需要注意的是,kruskal會被卡,要用prim (人題目給你矩陣還強行用kruskal也是醉),雖然突然不會prim了- - 接下來是第二問,那就很簡單了- -,建完圖,一求邊權平均數就可以了 1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 using namespace std; 5 typedef long long L; 6 inline L read(){ 7 L sum(0); 8 char ch(getchar()); 9 for(;ch<'0'||ch>'9';ch=getchar()); 10 for(;ch>='0'&&ch<='9';sum=sum*10+(ch^48),ch=getchar()); 11 return sum; 12 } 13 struct edge{ 14 L s,e,n; 15 L w; 16 }a[6001]; 17 L pre[2501],tot; 18 inline void insert(L s,L e,L w){ 19 a[++tot].s=s; 20 a[tot].e=e; 21 a[tot].w=w; 22 a[tot].n=pre[s]; 23 pre[s]=tot; 24 } 25 L T,n; 26 L dis[2501][2501],dis1[2501],dis2[2501][2501]; 27 L fa[2501]; 28 bool vis[2501]; 29 L degree[2501]; 30 double num[2501]; 31 inline void clear(){ 32 tot=0; 33 memset(pre,-1,sizeof(pre)); 34 memset(dis,0,sizeof(dis)); 35 memset(dis1,0x7f,sizeof(dis1)); 36 memset(dis2,0,sizeof(dis2)); 37 memset(fa,0,sizeof(fa)); 38 memset(vis,0,sizeof(vis)); 39 memset(degree,0,sizeof(degree)); 40 memset(num,0,sizeof(num)); 41 } 42 inline void prim(){ 43 dis1[1]=0; 44 for(L i=1;i<=n;i++){ 45 L k(0); 46 for(L j=1;j<=n;j++) 47 if(!vis[j]&&dis1[j]<dis1[k]) 48 k=j; 49 vis[k]=1; 50 for(L j=1;j<=n;j++) 51 if(!vis[j]&&dis[k][j]<dis1[j]) 52 dis1[j]=dis[k][j],fa[j]=k; 53 } 54 } 55 inline void build(){ 56 for(L i=2;i<=n;i++){ 57 insert(i,fa[i],dis1[i]); 58 insert(fa[i],i,dis1[i]); 59 degree[i]++,degree[fa[i]]++; 60 } 61 } 62 inline void dfs(L start,L now,L fa,L deep){ 63 for(L i=pre[now];i!=-1;i=a[i].n){ 64 L e(a[i].e); 65 if(e==fa) 66 continue; 67 dis2[start][e]=deep+a[i].w; 68 dfs(start,e,now,deep+a[i].w); 69 num[now]+=a[i].w; 70 num[e]+=a[i].w; 71 } 72 } 73 inline bool judge(){ 74 for(L i=1;i<=n;i++) 75 for(L j=1;j<=n;j++) 76 if(i!=j) 77 if(dis[i][j]!=dis2[i][j]&&dis2[i][j]>0) 78 return false; 79 return true; 80 } 81 int main(){ 82 // freopen("1.in","r",stdin); 83 // freopen("1.out","w",stdout); 84 T=read(); 85 while(T--){ 86 clear(); 87 n=read(); 88 for(L i=1;i<=n;i++){ 89 for(L j=1;j<=n;j++) 90 dis[i][j]=read(); 91 dis[i][i]=0x7fffffff; 92 } 93 if(n==1){ 94 puts("Yes"); 95 puts("1"); 96 continue; 97 } 98 prim(); 99 build(); 100 for(L i=1;i<=n;i++) 101 dfs(i,i,-1,0); 102 if(!judge()){ 103 puts("No"); 104 continue; 105 } 106 puts("Yes"); 107 double mx(0); 108 L ans(0); 109 for(L i=1;i<=n;i++){ 110 num[i]/=(double)degree[i]; 111 if(num[i]>mx) 112 mx=num[i],ans=i; 113 } 114 printf("%d\n",ans); 115 } 116 } View Code

?

轉載于:https://www.cnblogs.com/hzoi-mafia/p/7277670.html

總結

以上是生活随笔為你收集整理的[补档]藏宝图的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。