倍增LCA NOIP2013 貨車運輸
阿新 • • 發佈:2017-05-26
cmp cstring sta scanf 整數 clas 題目 can edge
貨車運輸
題目描述
A 國有 n 座城市,編號從 1 到 n,城市之間有 m 條雙向道路。每一條道路對車輛都有重量限制,簡稱限重。現在有 q 輛貨車在運輸貨物, 司機們想知道每輛車在不超過車輛限重的情況下,最多能運多重的貨物。
輸入輸出格式
輸入格式:
輸入文件名為 truck.in。
輸入文件第一行有兩個用一個空格隔開的整數 n,m,表示 A 國有 n 座城市和 m 條道
路。 接下來 m 行每行 3 個整數 x、 y、 z,每兩個整數之間用一個空格隔開,表示從 x 號城市到 y 號城市有一條限重為 z 的道路。註意: x 不等於 y,兩座城市之間可能有多條道路 。
接下來一行有一個整數 q,表示有 q 輛貨車需要運貨。
接下來 q 行,每行兩個整數 x、y,之間用一個空格隔開,表示一輛貨車需要從 x 城市運輸貨物到 y 城市,註意: x 不等於 y 。
輸出格式:
輸出文件名為 truck.out。
輸出共有 q 行,每行一個整數,表示對於每一輛貨車,它的最大載重是多少。如果貨
車不能到達目的地,輸出-1。
輸入輸出樣例
輸入樣例#1:4 3 1 2 4 2 3 3 3 1 1 3 1 3 1 4 1 3輸出樣例#1:
3 -1 3
說明
對於 30%的數據,0 < n < 1,000,0 < m < 10,000,0 < q< 1,000;
對於 60%的數據,0 < n < 1,000,0 < m < 50,000,0 < q< 1,000;
對於 100%的數據,0 < n < 10,000,0 < m < 50,000,0 < q< 30,000,0 ≤ z ≤ 100,000。
NOIP2013,kidding me?
出個模板題???
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 int n,m,q; 7 struct data{ 8 int s,e,d; 9 }edge[50010]; 10 int f[10010]; 11 struct dt{ 12 int next,to,dis; 13 }eg[20010]; 14 int cnt; 15 int head[10010],deep[10010],fa[10010][32],w[10010][32]; 16 bool cmp(const data&a,const data&b){ 17 return a.d>b.d;//! 18 } 19 int find(int x){ 20 if(x!=f[x]) return f[x]=find(f[x]);//! 21 return f[x];//! 22 } 23 void add(int start,int end,int dd){ 24 eg[++cnt].next=head[start]; 25 eg[cnt].to=end; 26 eg[cnt].dis=dd; 27 head[start]=cnt; 28 } 29 void build(){ 30 int ct=0; 31 for(int i=1;i<=m;i++){ 32 int f1=find(edge[i].s); 33 int f2=find(edge[i].e); 34 if(f1!=f2){ 35 f[f1]=f2; 36 add(edge[i].s,edge[i].e,edge[i].d); 37 add(edge[i].e,edge[i].s,edge[i].d); 38 ct++; 39 } 40 if(ct==n-1) break; 41 } 42 } 43 void dfs(int u){ 44 for(int i=head[u];i;i=eg[i].next) 45 if(!deep[eg[i].to]){ 46 deep[eg[i].to]=deep[u]+1; 47 fa[eg[i].to][0]=u; 48 w[eg[i].to][0]=eg[i].dis; 49 dfs(eg[i].to); 50 } 51 } 52 void work(){ 53 for(int j=1;(1<<j)<=n;j++) 54 for(int i=1;i<=n;i++) 55 if(fa[i][j-1]!=-1){ 56 fa[i][j]=fa[fa[i][j-1]][j-1]; 57 w[i][j]=min(w[i][j-1],w[fa[i][j-1]][j-1]); 58 } 59 } 60 int lca(int x,int y){ 61 int rt=0x3f3f3f3f; 62 if(deep[x]<deep[y]) swap(x,y); 63 int i=0; 64 for(i=0;(1<<i)<=deep[x];i++); 65 i--; 66 for(int j=i;j>=0;j--) 67 if(deep[x]-(1<<j)>=deep[y]){ 68 rt=min(rt,w[x][j]); 69 x=fa[x][j]; 70 } 71 if(x==y) return rt;//! 72 for(int j=i;j>=0;j--) 73 if(fa[x][j]!=-1&&fa[x][j]!=fa[y][j]){ 74 rt=min(rt,min(w[x][j],w[y][j])); 75 x=fa[x][j]; 76 y=fa[y][j]; 77 } 78 return min(rt,min(w[x][0],w[y][0])); 79 } 80 int main(){ 81 scanf("%d%d",&n,&m); 82 for(int i=1;i<=m;i++) scanf("%d%d%d",&edge[i].s,&edge[i].e,&edge[i].d); 83 sort(edge+1,edge+m+1,cmp); 84 for(int i=1;i<=n;i++) f[i]=i; 85 build(); 86 memset(fa,-1,sizeof(fa)); 87 deep[1]=1; 88 dfs(1); 89 work(); 90 scanf("%d",&q); 91 int ss=0,ee=0; 92 for(int i=1;i<=q;i++){ 93 scanf("%d%d",&ss,&ee); 94 if(find(ss)!=find(ee)){ 95 printf("-1\n"); 96 continue; 97 } 98 printf("%d\n",lca(ss,ee)); 99 } 100 return 0; 101 }
倍增LCA NOIP2013 貨車運輸