邦德市

来源:互联网 发布:签名设计软件 编辑:程序博客网 时间:2024/06/05 18:18
【问题描述】    邦德市有N(编号为1..N)个城市,用M条双向道路连接,每条道路都有一个危险系数。你的任务是回答若干询问,每个询问包含一个起点s和一个终点t,要求找到一条s到t的路径,使得路径上所有边的最大危险系数最小。【输入格式】    第一行一个包含两个整数N和M;  接下来的M行,每行包含三个整数:x,y,d(1<=x,y<=N0<=d<=1 000 000 000),即城市x于城市y有一条危险系数为d的双向道路。下一行一个整数Q,表示有Q个询问;  接下来的Q行,每行包含两个整数s,t(s!=t),表示一个询问的起点和终点。【输出格式】    对于每个询问,输出最优路线上所有边的危险系数的最大值。(输入数据保证所有城市是连通的)。【输入样例】  4 51 2 101 3 201 4 1002 4 303 4 1021 44 1【输出样例】  2020【数据范围】  对于30%的数据,满足1≤ n≤10001≤m≤100001≤q≤100; 对于50%的数据,满足1≤ n≤100001≤m≤100001≤q≤10000; 对于100%的数据,满足1≤ n≤100001≤m≤1000001≤q≤10000
#include<cstdio>#include<cstring>#include<algorithm>#include<vector>#include<cmath>#include<iostream>#define maxn 100005#define inf 11111111111111111using namespace std;struct data{    int a,b,l;};int n,m,x,y,z,t;long long oo=0,ans=inf;int fa[maxn],ha[maxn],dep[maxn]={0},dist[maxn]={0};vector<data>g;vector<int>p[maxn],q[maxn];bool vis[300005]={0};void clear()        //清空 {    for(int i=1;i<=n;i++) fa[i]=ha[i]=i;}int find(int x)     //查找 {    if(fa[x]==x) return x;    int t=find(fa[x]);    fa[x]=t;    return t;}void Union(int x,int y)     //合并 {    fa[find(x)]=find(y);}bool check(int x,int y)     //检查 {    return find(x)==find(y);}int getmax(int x,int y){    int Max=0;    if(dep[x]<dep[y]) swap(x,y);     while(dep[x]!=dep[y])    {        Max=max(Max,dist[x]-dist[fa[x]]);        x=fa[x];        }     while(x!=y)    {        Max=max(Max,dist[x]-dist[fa[x]]);        Max=max(Max,dist[y]-dist[fa[y]]);        x=fa[x];        y=fa[y];    }    return Max;} bool cmp(data xx,data yy){    return xx.l<yy.l;} void task()     //算出最小生成树 {    for(int i=0;i<g.size();i++)    {        int u=g[i].a,v=g[i].b;        if(check(u,v)) continue;        Union(u,v);        p[u].push_back(v);          //储存最小生成树的边         p[v].push_back(u);        q[v].push_back(g[i].l);     //距离         q[u].push_back(g[i].l);        vis[i]=true;        oo=g[i].l;    }}void fuck(int x,int y,int z)        //x,x的父亲,x的层数 {    fa[x]=y;    dep[x]=z;    for(int i=0;i<p[x].size();i++)    {        int j=p[x][i];         if(j==y) continue;                      dist[j]=dist[x]+q[x][i];        fuck(j,x,z+1);                  }}int main(){    //freopen("in.txt","r",stdin);    scanf("%d%d",&n,&m);    for(int i=1;i<=m;i++)    {           scanf("%d%d%d",&x,&y,&z);        g.push_back((data){x,y,z});     }    sort(g.begin(),g.end(),cmp);    clear();    task();    fuck(1,1,1);     //(1,1的父亲,层数)     scanf("%d",&t);    while(t--)    {        scanf("%d%d",&x,&y);        if(y>x) swap(x,y);        int ans=getmax(x,y);        printf("%d\n",ans);    }    return 0;}
0 0
原创粉丝点击