bzoj 1050 [HAOI2006]旅行comf [最小生成树] [动点spfa] [LCT]

原创 2016年08月30日 17:05:35

1050: [HAOI2006]旅行comf

Time Limit: 10 Sec Memory Limit: 162 MB
Submit: 2740 Solved: 1486

Description

  给你一个无向图,N(N<=500)个顶点, M(M<=5000)条边,每条边有一个权值Vi(Vi<30000)。给你两个顶点S和T
,求一条路径,使得路径上最大边和最小边的比值最小。如果S和T之间没有路径,输出”IMPOSSIBLE”,否则输出
这个比值,如果需要,表示成一个既约分数。 备注: 两个顶点之间可能有多条路径。

Input

  第一行包含两个正整数,N和M。下来的M行每行包含三个正整数:x,y和v。表示景点x到景点y之间有一条双向
公路,车辆必须以速度v在该公路上行驶。最后一行包含两个正整数s,t,表示想知道从景点s到景点t最大最小速
度比最小的路径。s和t不可能相同。
1

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<string>
#include<iomanip>
#include<ctime>
#include<climits>
#include<cctype>
#include<algorithm>
#ifdef WIN32
#define AUTO "%I64d"
#else
#define AUTO "%lld"
#endif
using namespace std;
#define smax(x,tmp) x=max((x),(tmp))
#define smin(x,tmp) x=min((x),(tmp))
#define maxx(x1,x2,x3) max(max(x1,x2),x3)
#define minn(x1,x2,x3) min(min(x1,x2),x3)
typedef long long LL;
const int INF=0x3f3f3f3f;
const int maxn = 505;
const int maxm = 5005;
LL gcd(LL a,LL b)
{
    if(!b) return a;
    return gcd(b,a%b);
}
struct Fraction
{
    LL numer,deno; // numerator/denominator
    void reduce()
    {
        LL GCD = gcd(numer,deno);
        numer/=GCD; deno/=GCD;
    }
    Fraction (const LL a,const LL b) { numer=a,deno=b; reduce();  }
    bool operator < (const Fraction t) const
    {
        LL GCD=gcd(deno,t.deno);
        LL a1=numer*t.deno/GCD;
        LL a2=t.numer*deno/GCD;
        return a1 < a2;
    }
    bool operator == (Fraction t)
    {
        reduce(); t.reduce();
        return numer==t.numer && deno==t.deno;
    }
};
struct Edge
{
    int to,next;
    int val;
}edge[maxm<<1];
int head[maxn];
int maxedge;
inline void addedge(int u,int v,int c)
{
    edge[++maxedge] = (Edge) { v,head[u],c };
    head[u] = maxedge;
    edge[++maxedge] = (Edge) { u,head[v],c };
    head[v] = maxedge;
}
struct Road
{
    int u,v;
    int c;
    bool operator < (const Road t) const { return c > t.c; }
}road[maxm];
int n,m,S,T;
inline void init()
{
    scanf("%d%d",&n,&m);
    memset(head,-1,sizeof(head));
    maxedge=-1;
    for(int i=1;i<=m;i++)
        scanf("%d%d%d",&road[i].u,&road[i].v,&road[i].c);
    sort(road+1,road+m+1); //decending order
    scanf("%d%d",&S,&T);
}
queue <int> que;
bool inque[maxn];
int dis[maxn];
void spfa()
{
    while(!que.empty())
    {
        int u=que.front();que.pop();inque[u]=false;
        for(int i=head[u];~i;i=edge[i].next)
        {
            int v=edge[i].to;
            if(dis[v]>max(dis[u],edge[i].val))
            {
                dis[v]=max(dis[u],edge[i].val);
                if(inque[v]) continue;
                inque[v]=true;
                que.push(v);
            }
        }
    }
}
Fraction work()
{
    Fraction ans=Fraction(INF,1);
    memset(dis,0x3f,sizeof(dis));
    memset(inque,0,sizeof(inque));
    dis[S]=0;
    for(int i=1;i<=m;i++)
    {
        addedge(road[i].u,road[i].v,road[i].c);
        que.push(road[i].u); que.push(road[i].v);
        spfa();
        smin(ans,dis[T]<INF?Fraction(dis[T],road[i].c):Fraction(INF,1));
    }
    return ans;
}
void print(Fraction t)
{
    printf("%d",t.numer);
    if(t.deno^1ll) printf("/%d",t.deno);
    putchar('\n');
}
int main()
{
#ifndef ONLINE_JUDGE
    freopen("comf.in","r",stdin);
    freopen("comf.out","w",stdout);
#endif
    init();
    Fraction ans=work();
    if(ans==Fraction(INF,1)) puts("IMPOSSIBLE");
    else print(ans);
    return 0;
}
版权声明:S'il vous plait.

相关文章推荐

BZOJ 1050 HAOI2006 旅行comf 动点SPFA

题目大意:给定一个无向图,每条边上有权值,求起点到终点的路径中最长边和最短边的最小比值 随手点开一道居然是动点SPFA的裸题…… 魔法森林都切了这个问题就不大了 我们把边权排序,从大到小加进这个图...
  • PoPoQQQ
  • PoPoQQQ
  • 2014年10月30日 14:21
  • 1491

bzoj 1050: [HAOI2006]旅行comf(最小生成树+并查集)

1050: [HAOI2006]旅行comf Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 2405  Solved: 1282 [Submi...

BZOJ 1050 HAOI 2006 旅行comf SPFA动态加点

题目大意:给出S和T,求从S到T的最长边/最短边的最小值(分数形式输出)。 思路:和NOI2014的魔法森林很像啊,比较裸地动态加边,按照边的权值从大到小排序,然后一条一条的加进去,f[i]...

[BZOJ]1050: [HAOI2006]旅行comf SPFA

Description   给你一个无向图,N(N ,求一条路径,使得路径上最大边和最小边的比值最小。如果S和T之间没有路径,输出”IMPOSSIBLE”,否则输出 这个比值,如果需要,表示...

BZOJ1050(HAOI2006)[旅行comf]--并查集

bzoj1050
  • CHNWJD
  • CHNWJD
  • 2017年06月30日 22:51
  • 148

【bzoj1050】[HAOI2006]旅行comf

1050: [HAOI2006]旅行comf Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 3376  Solved: 1875 [Submit][...

【BZOJ 1050】 [HAOI2006]旅行comf

对kruscal的变形~ kruscal运用到路径问题中~ 详细题解~

bzoj 1050: [HAOI2006]旅行comf(尺取+最短路)

1050: [HAOI2006]旅行comf Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 3335  Solved: 1852 [Submit][...

[并查集]BZOJ 1050——[HAOI2006]旅行comf

1050: [HAOI2006]旅行comf题目描述给你一个无向图,N(N
  • CHN_JZ
  • CHN_JZ
  • 2017年06月30日 13:44
  • 1553

[BZOJ 1050] HAOI 2006 旅行comf · Kruskal

网上有非常吊炸天的LCT做法 并不会23333 用Kruskal来做的思路比较神奇但是很简单 首先把所有的边按照权值排序 顺次枚举每一条边,从这条边开始做Kruskal,直到S和T联通,这就是...
  • ycdfhhc
  • ycdfhhc
  • 2017年07月25日 16:20
  • 92
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:bzoj 1050 [HAOI2006]旅行comf [最小生成树] [动点spfa] [LCT]
举报原因:
原因补充:

(最多只允许输入30个字)