• 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);
        }
    }
  • 相关阅读:
    常看本地是否安装Git和maven工具
    Git 安装和使用Tips
    Jmeter 获取系统时间,和对系统时间进行增减时间
    Java 中的系统时间
    Go语言
    数据拆分之 垂直拆分 and 水平拆分
    在Windows和UNIX下利用PHP和LDAP进行身份验证
    Linux中使用crontab命令定时执行shell脚本或其他Linux命令
    php empty()和isset()的区别
    php 判断是否get传值的参数是否存在
  • 原文地址:https://www.cnblogs.com/Narh/p/8613285.html
Copyright © 2020-2023  润新知