zoukankan      html  css  js  c++  java
  • 灾后重建(最短路)

    60分做法:

    暴力跑dijkstra即可

    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<iostream>
    #include<cstdio>
    #include<queue>
    using namespace std;
    typedef long long ll;
    const int maxm=210;
    int n,m,q;
    int t[maxm];
    int pre[maxm*maxm],last[maxm],len[maxm*maxm],other[maxm*maxm],l;
    bool vis[maxm];
    int dis[maxm];
    void add(int x,int y,int z)
    {
     l++;
     pre[l]=last[x];
     last[x]=l;
     other[l]=y;
     len[l]=z;	
    }
    void dijkstra(int a,int b,int c)
    {
     priority_queue<pair<int,int> > q;
     memset(dis,63,sizeof(dis));
     memset(vis,0,sizeof(vis));
     dis[a]=0;
     q.push(make_pair(0,a));
     while(q.size())
     {
       int u=q.top().second;
       q.pop();
       if(vis[u]) continue;
       vis[u]=1;
       if(u==b) return;
       for(int p=last[u];p;p=pre[p])
       {
        int v=other[p];
        if(dis[v]>dis[u]+len[p]&&t[v]<=c)
        {
          dis[v]=dis[u]+len[p];
    	  q.push(make_pair(-dis[v],v));	
        }
       }
     }	
    }
    int main()
    {
     scanf("%d%d",&n,&m);
     for(int i=1;i<=n;i++)
     scanf("%d",&t[i]);
     for(int i=1;i<=m;i++)
     {
      int x,y,z;
      scanf("%d%d%d",&x,&y,&z);
      x++;
      y++;
      add(x,y,z);
      add(y,x,z);	
     }
     scanf("%d",&q);
     for(int i=1;i<=q;i++)
     {
       int x,y,z;
       scanf("%d%d%d",&x,&y,&z);
       x++;
       y++;
       if(z<t[x]||z<t[y])
       {
       	 printf("-1
    ");
       	 continue;
       }
       dijkstra(x,y,z);
       if(!vis[y])
       {
       	printf("-1
    ");
       	continue;
       }
       printf("%d
    ",dis[y]);
     }
     return 0;	
    }
    

    满分做法:

    按照时间顺序更新每一个可用的点(即修建好村庄),对于每个时间点进行两点之间询问,求对于目前建设的所有村庄来说任意两点之间的最短路。这就是Floyd的思想!

    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<iostream>
    #include<cstdio>
    #include<queue>
    using namespace std;
    typedef long long ll;
    const int maxm=210;
    int n,m,q;
    int t[maxm];
    int dis[maxm][maxm];
    void init(int x)
    {
     for(int i=1;i<=n;i++)
     {
      for(int j=1;j<=n;j++)
      dis[i][j]=min(dis[i][j],dis[i][x]+dis[x][j]);
     }
    }
    int main()
    {
     scanf("%d%d",&n,&m);
     for(int i=1;i<=n;i++)
     scanf("%d",&t[i]);//数据保证单调递增 
     memset(dis,63,sizeof(dis));
     for(int i=1;i<=n;i++)
     dis[i][i]=0;
     for(int i=1;i<=m;i++)
     {
      int x,y,z;
      scanf("%d%d%d",&x,&y,&z);
      x++;
      y++;
      if(z<dis[x][y])dis[x][y]=dis[y][x]=z;
     }
     int now=1;
     scanf("%d",&q);
     for(int i=1;i<=q;i++)
     {
       int x,y,z;
       scanf("%d%d%d",&x,&y,&z);//z是单增的 
       x++;
       y++;
       while(t[now]<=z&&now<=n)//有些村庄修好后可以直接更新各个最短路情况 
       {
       	 init(now);
       	 now++;
       }
       if(t[x]>z||t[y]>z||dis[x][y]==dis[0][0])
       {
       	printf("-1
    ");
       }
       else
       printf("%d
    ",dis[x][y]);
     }
     return 0;	
    }
    
  • 相关阅读:
    常用WebService一览表
    Generic Data Access Objects [转]
    spring hibernate properties详解
    SpringMVC常用基础知识【转】
    向PLSQL导入txt,csv文件
    打印金字塔图案
    经常使用的文件工具类
    求两个数的最大公约数
    155个建议笔记1
    用Tika读取文件(不需要考虑文件格式)
  • 原文地址:https://www.cnblogs.com/lihan123/p/11692379.html
Copyright © 2011-2022 走看看