YYHS-論戰大原題
阿新 • • 發佈:2017-09-15
旁觀者 表示 printf class 是否 輸出 wid 隨機生成 ace
第一行兩個整數n,m,k。
接下來m行每行三個整數u,v,w,表示u到v存在一條長度為w的無向邊。
dist(1,2)=4 dist(1,3)=3 dist(1,4)=3 dist(2,3)=3 dist(2,4)=3 dist(3,4)=5
故第2大的dist(i,j)為4
【限制與約定】
對於所有的數據,保證n≤100000,m≤min(n2,200000),k≤n(n-1)/2且圖連通,w≤109。
題目描述
Abwad最終造出了一道驚世駭俗的難題——在線詢問動態仙人球上第k長的路徑的所有後綴的不同的回文子串數,可是nbc只瞄了一眼題面,就說出了Abwad冥思苦想了三天三夜才得到的算法。 為了扭轉劣勢,Abwad決定和nbc論戰大原題。規則很簡單,即給出一道原題,比誰能更快地找出原題的出處並將其AC。現在擺在他們面前的是這樣一道原題: 給定一個n個點m條邊的無向圖。定義一條路徑的長度為路徑上最小邊的權值。定義dist(i,j)為起點為i,終點為j的長度最長的路徑的長度。求出第k大的dist(i,j)(i<j)。 Abwad依稀記得這道題曾經出現在一場名叫“恩偶愛皮”的比賽中。在搜索引擎的幫助下,他開始以50Hz的手速寫起了代碼。作為旁觀者的你,一眼就看出Abwad看錯題了。為了證明他是錯的,請你寫個程序,求出答案。輸入
輸出
一行一個整數ans,為第k大的dist(i,j)樣例輸入
4 5 2 1 2 4 4 3 5 2 3 2 4 1 1 3 1 3樣例輸出
4提示
【樣例說明】
dist(1,2)=4 dist(1,3)=3 dist(1,4)=3 dist(2,3)=3 dist(2,4)=3 dist(3,4)=5
故第2大的dist(i,j)為4
【限制與約定】
測試點編號 |
n |
m |
k |
特殊約定 |
1 |
n≤100 | |||
2 |
||||
3 |
||||
4 |
||||
5 |
n≤1000 |
m=n-1 |
u=v-1 |
|
6 |
||||
7 |
數據隨機生成 |
|||
8 |
||||
9 |
||||
10 |
||||
11 |
n≤100000 n≤100000 |
k=1 k=1 |
||
12 |
||||
13 |
m=n-1 |
u=v-1 |
||
14 |
||||
15 |
||||
16 |
||||
17 |
數據隨機生成 |
|||
18 | ||||
19 |
||||
20 |
對於所有的數據,保證n≤100000,m≤min(n2,200000),k≤n(n-1)/2且圖連通,w≤109。
題解
這道題是貪心+並查集
按w值從大到小排序,枚舉邊,判斷這條邊的兩個端點是不是在同一個集合,如果不在同一個集合,那麽這兩個集合之間的任意兩個點之間的dist就是當前這條邊的w值(因為以前加進去的邊都不小於這條邊),就把兩個集合的點數相乘,再用計數器加起來判斷是否超過k即可
#include<bits/stdc++.h> #define ll long long #define N 100005 #define M 200005 using namespace std; int n,m,f1,f2; ll k,num; int fa[N]; ll sum[N]; struct zcr{ int x,y,v; }a[M]; bool cmp(zcr x,zcr y){ return x.v>y.v;} int getfather(int x){ if (x!=fa[x]) fa[x]=getfather(fa[x]);return fa[x];} int main(){ scanf("%d%d%lld",&n,&m,&k); for (int i=1;i<=n;i++) fa[i]=i,sum[i]=1; for (int i=1;i<=m;i++) scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].v); sort(a+1,a+1+m,cmp); num=0; for (int i=1;i<=m;i++){ f1=getfather(a[i].x); f2=getfather(a[i].y); if (f1!=f2){ num+=sum[f1]*sum[f2]; if (num>=k){ printf("%d\n",a[i].v); return 0; } fa[f1]=f2; sum[f2]+=sum[f1]; } } return 0; }View Code
YYHS-論戰大原題