刷題總結——貨車運輸
阿新 • • 發佈:2017-08-15
等於 nbsp from name include () math 雙向 names
題目:
題目背景
NOIP2013 提高組 Day1 試題。
題目描述
A 國有 n 座城市,編號從 1 到 n,城市之間有 m 條雙向道路。每一條道路對車輛都有重量限制,簡稱限重。現在有 q 輛貨車在運輸貨物,司機們想知道每輛車在不超過車輛限重的情況下,最多能運多重的貨物。
輸入格式
第一行有兩個用一個空格隔開的整數 n ,m,表示 A 國有 n 座城市和 m 條道路。
接下來 m 行每行 3 個整數 x、y、z,每兩個整數之間用一個空格隔開,表示從 x 號城市到 y 號城市有一條限重為 z 的道路。註意:x 不等於 y,兩座城市之間可能有多條道路。
?接下來一行有一個整數 q,表示有 q 輛貨車需要運貨。
接下來 q 行,每行兩個整數 x、y,之間用一個空格隔開,表示一輛貨車需要從 x 城市運輸貨物到 y 城市,註意:x 不等於 y。
輸出格式
輸出共有 q 行,每行一個整數,表示對於每一輛貨車,它的最大載重是多少。如果貨車不能到達目的地,輸出 -1。
樣例數據 1
輸入 [復制]
4 3
1 2 4
2 3 3
3 1 1
3
1 3
1 4
1 3
輸出
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。
題解:
最大生成樹然後在樹上倍增就可以了···md並查集竟然打掛卡了我半天···
突然發現倍增法那麽有用····
代碼:
#include<cstdio> #include<cstdlib> #include<cmath> #include<ctime> #include<cctype> #include<cstring> #include<string> #include<algorithm> #include<iostream> using namespace std; constint N=1e5+5; const int M=5e5+5; int R() { int f=0; char c; for(c=getchar();c<‘0‘||c>‘9‘;c=getchar()); for(;c>=‘0‘&&c<=‘9‘;c=getchar()) f=(f<<3)+(f<<1)+c-‘0‘; return f; } int n,m,first[N],go[M],val[M],next[M],q,tot=0,g[N][35],deep[N],minn[N][35],father[N]; bool visit[N]; struct node { int from; int go; int w; }edge[M]; inline int getfa(int a) { if(father[a]==a) return a; else { father[a]=getfa(father[a]); return father[a]; } } bool cmp(node a,node b) { return a.w>b.w; } void comb(int a,int b,int c) { next[++tot]=first[a],first[a]=tot,go[tot]=b,val[tot]=c; next[++tot]=first[b],first[b]=tot,go[tot]=a,val[tot]=c; } inline void dfs(int now,int fa) { visit[now]=true; for(int e=first[now];e;e=next[e]) { int v=go[e]; if(v==fa||visit[v]==true) continue; g[v][0]=now; minn[v][0]=max(val[e],minn[v][0]); deep[v]=deep[now]+1; dfs(v,now); } } inline int getans(int x,int y) { int minx=1e+9,miny=1e+9,i,j; if(deep[x]<deep[y]) swap(x,y); for(i=0;(1<<i)<=deep[x];i++); i--; for(j=i;j>=0;j--) { if(deep[x]-(1<<j)>=deep[y]) { minx=min(minx,minn[x][j]); x=g[x][j]; } } if(x==y) return minx; for(i=32;i>=0;i--) { if(g[x][i]!=g[y][i]) { minx=min(minx,minn[x][i]); miny=min(miny,minn[y][i]); x=g[x][i]; y=g[y][i]; } } minx=min(minx,minn[x][0]); miny=min(miny,minn[y][0]); return min(minx,miny); } int main() { //freopen("a.in","r",stdin); n=R(),m=R(); for(int i=1;i<=n;i++) father[i]=i; int x,y,z; for(int i=1;i<=m;i++) { x=R(),y=R(),z=R(); edge[i].from=x; edge[i].go=y; edge[i].w=z; } sort(edge+1,edge+m+1,cmp); for(int i=1;i<=m;i++) { if(getfa(edge[i].from)!=getfa(edge[i].go)) { father[getfa(edge[i].from)]=getfa(edge[i].go); comb(edge[i].from,edge[i].go,edge[i].w); } } for(int i=1;i<=n;i++) { if(!visit[i]) { dfs(i,0); minn[i][0]=1e+9; g[i][0]=i; } } for(int i=1;i<=32;i++) for(int j=1;j<=n;j++) { g[j][i]=g[g[j][i-1]][i-1]; minn[j][i]=min(minn[g[j][i-1]][i-1],minn[j][i-1]); } q=R(); while(q--) { x=R(),y=R(); if(getfa(x)!=getfa(y)) cout<<"-1"<<endl; else cout<<getans(x,y)<<endl; } return 0; }
刷題總結——貨車運輸