Competition Day

题目描述

Matt, Nick and Tim are all best friends who flat together and regularly compete in programming competitions. A big competition is coming up, and as Matt recently learned C# he would like to show off his skills and compete against Nick and Tim. However Nick and Tim are certain their combined Fortran 95 skill will triumph against Matt.
Nick suggests that on the competition day they take a different route to the competition than Matt does to get in his head. To ensure Matt sees this different route they take, they will leave at the same time from
their flat. Unfortunately for Nick and Tim, Matt is one step ahead and has already planned out the fastest route to the competition from their flat!
Tim hates to waste petrol on the same scenery, and therefore they will not visit the same place twice on their route. The potential routes from the flat to the competition will include N junctions and M directed roads connecting these junctions. Each road has a time T associated with it (in minutes) for how long it takes to drive down and these measurements are well known. The flat and competition site are located at different junctions.
How long after Matt will Nick and Tim arrive (in minutes) if they take the fastest route which is different from Matt’s route?

 

输入

Input will begin with a line containing four integers, N, M, F, C. 2 ≤ N ≤ 8000, 1 ≤ M ≤ 8000, 1 ≤ F, C ≤ N
N is is the number of junctions and M is the number of roads. F and C represent the junction number of the flat and competition site respectively.
M lines will follow with three integers i, j and T, 1 ≤ i, j ≤ N representing a unidirectional road from junction i to junction j taking T minutes. T is a positive integer. 0 < T ≤ 2 × 105
Input will contain many test cases.
The last case will be denoted by N and M being 0.
There will always be a path from the flat to the competition site.
No two roads connect the same pair of junctions in the same direction. No road connects a junction to itself.

 

输出

Output how many minutes Nick and Tim will arrive after Matt.
If Nick and Tim can not take a different route, print ”Matt wins.” as they have failed to get in his head.

 

样例输入

复制样例数据

2 1 1 2
1 2 1
3 3 1 3
1 2 1
2 3 1
1 3 3
0 0 0 0

样例输出

Matt wins.
1

 

疯狂跑最短路就好了,判断是否有多条最短路,进行剪枝,其他情况跑就完事了

#pragma GCC optimize("Ofast","inline","-ffast-math")
#pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const ll mod=1e9+7;
const int modp=998244353;
const int maxn=1e6+50;
const double eps=1e-6;
#define lowbit(x)  x&(-x)
#define INF 0x3f3f3f3f
inline ll read()
{
    ll x=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9')
    {
        if(ch=='-')
            f=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9')
    {
        x=x*10+ch-'0';
        ch=getchar();
    }
    return x*f;
}
int dcmp(double x)
{
    if(fabs(x)0)?1:-1;
}
int gcd(int a,int b)
{
    return b?gcd(b,a%b):a;
}
ll qmod(ll a,ll b)
{
    ll ans=1;
    while(b)
    {
        if(b&1)
        {
            ans=(ans*a)%mod;
        }
        b>>=1;
        a=(a*a)%mod;
    }
    return ans;
}
const int N=8050,M=8050;
int d[N];
int head[N],ver[M],edge[M],nex[M],d1[N];
int head2[N],ver2[M],edge2[M],nex2[M],d2[N];
bool v[N];
bool mark[N];
int n,m,tot,tot2;
struct node
{
    int u,v,w;
} ee[8050];
void addedge(int x,int y,int z)
{
    ver[++tot]=y;
    edge[tot]=z;
    nex[tot]=head[x];
    head[x]=tot;
}

void addedge2(int x,int y,int z)
{
    ver2[++tot2]=y;
    edge2[tot2]=z;
    nex2[tot2]=head2[x];
    head2[x]=tot2;
}

void dijkstra(int s)
{
    for(int i=0;i<=n;++i){
        d[i]=INF;
        v[i]=0;
    }
    d[s]=0;
    priority_queue > q;
    q.push(make_pair(0,s));
    while(q.size())
    {
        int x=q.top().second;
        q.pop();
        if(v[x])continue;
        v[x]=1;
        for(int i=head[x]; i; i=nex[i])
        {
            int y=ver[i],z=edge[i];
            if(d[y]>d[x]+z)
            {
                d[y]=d[x]+z;
                q.push(make_pair(-d[y],y));
            }
        }
    }
}
void dijkstra1(int s)
{
    for(int i=0;i<=n;++i){
        d1[i]=INF;
        v[i]=0;
    }
    d1[s]=0;
    priority_queue > q;
    q.push(make_pair(0,s));
    while(q.size())
    {
        int x=q.top().second;
        q.pop();
        if(v[x])continue;
        v[x]=1;
        for(int i=head[x]; i; i=nex[i])
        {
            int y=ver[i],z=edge[i];
            if(d1[y]>d1[x]+z)
            {
                d1[y]=d1[x]+z;
                q.push(make_pair(-d1[y],y));
            }
        }
    }
}
void dijkstra2(int s)
{
    for(int i=0;i<=n;++i){
        d2[i]=INF;
        v[i]=0;
    }
    d2[s]=0;
    priority_queue > q;
    q.push(make_pair(0,s));
    while(q.size())
    {
        int x=q.top().second;
        q.pop();
        if(v[x])continue;
        v[x]=1;
        for(int i=head2[x]; i; i=nex2[i])
        {
            int y=ver2[i],z=edge2[i];
            if(d2[y]>d2[x]+z)
            {
                d2[y]=d2[x]+z;
                q.push(make_pair(-d2[y],y));
            }
        }
    }
}
int main()
{
    while(1)
    {
        int s,t;
        n=read();
        m=read();
        s=read();
        t=read();
        if(n==0&&m==0)
        {
            break;
        }
        tot=0;
        tot2=0;
        for(int i=1;i<=n;++i){
            head2[i]=head[i]=0;
            mark[i]=0;
        }
        for(int i=1; i<=m; ++i)
        {
            ee[i].u=read();
            ee[i].v=read();
            ee[i].w=read();
            addedge(ee[i].u,ee[i].v,ee[i].w);
            addedge2(ee[i].v,ee[i].u,ee[i].w);
        }
        dijkstra1(s);
        dijkstra2(t);
        int ans=d1[t];
        int res=INF;
        for(int i=1; i<=m; ++i)
        {
            if(d1[ee[i].u]+d2[ee[i].v]+ee[i].w==ans){
                if(mark[ee[i].v]){
                    res=ans;
                    break;
                }
                else{
                    mark[ee[i].v]=1;
                }
                edge[i]=INF;
                dijkstra(s);
                res=min(res,d[t]);
                edge[i]=ee[i].w;
            }
        }
        if(res==INF){
            printf("Matt wins.\n");
        }
        else{
            printf("%d\n",res-ans);
        }
    }
}

 

你可能感兴趣的:(图)