• POJ1135 Domino Effect(SPFA)


    题目大概是,普通骨牌连接两张关键骨牌,一旦一张关键骨牌倒下与其相邻的普通骨牌也倒下,普通骨牌倒下与其相邻的骨牌也倒下。给出所有有普通骨牌相连的两个关键骨牌之间普通骨牌倒下所需时间,问1号关键骨牌开始倒下后最后一张骨牌倒下的时间和位置。

    居然是最短路。。记dist[u]为起点骨牌1到关键骨牌u的最短时间,跑个单源最短路可得出。最后倒下的骨牌,有两种情况:

    1. 倒下的是关键骨牌u,那么倒下的时间就是dist[u]
    2. 倒下的是关键骨牌u和v之间某张普通骨牌,那么倒下的时间就是 (dist[u]+dist[v]+time(u,v))/2,因为:
      • dist[u]=dist[v]显然成立,不等于的情况不妨设dist[u]<dist[v];
      • 那么过了dist[u]的时间后,通往u点的骨牌到正好达u点,而通往v点的还需dist[v]-dist[u]的时间到达v;
      • 因而两边这时还有dist[v]-dist[u]+time(u,v)的时间长度,两边同时倒就还需要(dist[v]-dist[u]+time(u,v))/2的时间;
      • 所以总共需要(dist[v]-dist[u]+time(u,v))/2+dist[u],即(dist[v]+dist[u]+time(u,v))/2的时间。

    这样分别搞搞这两种情况,就能找到答案。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<queue>
     4 #include<algorithm>
     5 using namespace std;
     6 #define MAXN 555
     7 #define MAXM 555*555*2
     8 
     9 struct Edge{
    10     int u,v,cost,next;
    11 }edge[MAXM];
    12 int head[MAXN],NE,n;
    13 void addEdge(int a,int b,int c){
    14     edge[NE].u=a; edge[NE].v=b; edge[NE].cost=c; edge[NE].next=head[a];
    15     head[a]=NE++;
    16 }
    17 
    18 int d[MAXN];
    19 void SPFA(int vs){
    20     memset(d,127,sizeof(d));
    21     d[vs]=0;
    22     bool vis[MAXN]={0};
    23     vis[vs]=1;
    24     queue<int> que;
    25     que.push(vs);
    26     while(!que.empty()){
    27         int u=que.front(); que.pop();
    28         for(int i=head[u]; i!=-1; i=edge[i].next){
    29             int v=edge[i].v;
    30             if(d[v]>d[u]+edge[i].cost){
    31                 d[v]=d[u]+edge[i].cost;
    32                 if(!vis[v]){
    33                     vis[v]=1;
    34                     que.push(v);
    35                 }
    36             }
    37         }
    38         vis[u]=0;
    39     }
    40 }
    41 int main(){
    42     int m,a,b,c,cse=0;
    43     while(~scanf("%d%d",&n,&m) && (n||m)){
    44         NE=0;
    45         memset(head,-1,sizeof(head));
    46         while(m--){
    47             scanf("%d%d%d",&a,&b,&c);
    48             addEdge(a,b,c);
    49             addEdge(b,a,c);
    50         }
    51         SPFA(1);
    52         double res=-1;
    53         bool flag=0;
    54         for(int i=1; i<=n; ++i){
    55             if(d[i]>res){
    56                 res=d[i];
    57                 a=i;
    58             }
    59         }
    60         for(int i=0; i<NE; i+=2){
    61             double tmp=(d[edge[i].u]+d[edge[i].v]+edge[i].cost)/2.0;
    62             if(tmp>res){
    63                 res=tmp;
    64                 flag=1;
    65                 a=edge[i].u; b=edge[i].v;
    66                 if(a>b) swap(a,b);
    67             }
    68         }
    69         printf("System #%d
    ",++cse);
    70         if(flag) printf("The last domino falls after %.1f seconds, between key dominoes %d and %d.
    
    ",res,a,b);
    71         else printf("The last domino falls after %.1f seconds, at key domino %d.
    
    ",res,a);
    72     }
    73     return 0;
    74 }
  • 相关阅读:
    设计模式:观察者模式
    设计模式:享元模式
    面试题:redis主从数据库不一致如何解决?
    面试题:Object obj = new Object()这句话在内存里占用了多少字节
    面试题:AtomicInteger和LongAdder区别
    @PrePersist 注解
    树莓派 zero w 添加微雪墨水屏 显示天气
    数据仓库项目中的数据建模和ETL日志体系
    TO B业务的发展
    Kylin、Druid、ClickHouse核心技术对比
  • 原文地址:https://www.cnblogs.com/WABoss/p/5271469.html
Copyright © 2020-2023  润新知