POJ1135 Domino Effect

题目:http://poj.org/problem?id=1135

只是求以1为起点的最短路罢了。稍稍判断一下在边上的情况。

多亏提醒:毒数据——n==1!一定要dis [ k ] >= ans!!!

注意输出格式(换行)。

#include<iostream>
#include<cstdio>
#include<cstring>
#define ll long long
using namespace std;
int n,m,head[505],xnt,x,y,T;
int hp[5005],cnt,k1,k2;
ll dis[505],z;
double ans;
bool vis[505];
struct Edge{
    int next,to;
    ll w;
    Edge(int a=0,int b=0,ll c=0):next(a),to(b),w(c) {}
}edge[500005];
ll abss(ll k)
{
    if(k<0)k=-k;
    return k;
}
void push(int k)
{
    hp[++cnt]=k;
    int now=cnt;
    while(now>1)
    {
        int tp=(now>>1);
        if(dis[hp[now]]<dis[hp[tp]])swap(hp[now],hp[tp]);
        else break;
        now=tp;
    }
}
int del()
{
    int res=hp[1];
    hp[1]=hp[cnt--];
    int now=1;
    while((now<<1)<=cnt)
    {
        int tp=(now<<1);
        if(tp<cnt&&dis[hp[tp+1]]<dis[hp[tp]])tp++;
        if(dis[hp[tp]]<dis[hp[now]])swap(hp[tp],hp[now]);
        else break;
        now=tp;
    }
    return res;
}
int main()
{
    while(++T)
    {
        scanf("%d%d",&n,&m);
        if(!n&&!m)return 0;
        memset(dis,11,sizeof dis);
        memset(head,0,sizeof head);
        memset(vis,0,sizeof vis);
        xnt=0;ans=0;k1=0;k2=0;
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d%lld",&x,&y,&z);
            edge[++xnt]=Edge(head[x],y,z);head[x]=xnt;
            edge[++xnt]=Edge(head[y],x,z);head[y]=xnt;
        }
        dis[1]=0;push(1);
        while(cnt)
        {
            int k=del();
            while(cnt&&vis[k])k=del();
            if(vis[k])break;
            vis[k]=1;
            if(dis[k]>=ans)//////////
            {
                ans=dis[k];k1=k;
            }
            for(int i=head[k],v;i;i=edge[i].next)
                if(!vis[v=edge[i].to]&&dis[k]+edge[i].w<dis[v])
                {
                    dis[v]=dis[k]+edge[i].w;
                    push(v);
                }
        }
        double c=0;
        for(int i=1;i<=n;i++)
            for(int j=head[i],v;j;j=edge[j].next)
                if(abss(dis[i]-dis[v=edge[j].to])<edge[j].w&&
                    (c=max(dis[i],dis[v])+(double)(edge[j].w-abss(dis[i]-dis[v]))/2)>ans)
                    {
                        ans=c;k1=min(i,v);k2=max(i,v);
                    }
        printf("System #%d
",T);
        if(!k2)
            printf("The last domino falls after %.1lf seconds, at key domino %d.

",ans,k1);
        else 
            printf("The last domino falls after %.1lf seconds, between key dominoes %d and %d.

",ans,k1,k2);
    }
}
原文地址:https://www.cnblogs.com/Narh/p/8613285.html