zoukankan      html  css  js  c++  java
  • LightOJ 1074 Extended Traffic(spfa+dfs标记负环上的点)

    题目链接:https://cn.vjudge.net/contest/189021#problem/O

    题目大意:有n个站点,每个站点都有一个busyness,从站点A到站点B的花费为(busyness of B  -  busyness of A)^3。给出个站点间的连通关系(单向),有q次询问,每次询问站点1到x(1<=x<=n)的最小花费,若x点无法到达或者花费小于3则输出‘?’。

    解题思路:还是最短路问题,但是图中有负环的存在,所以要判断负环,每次发现负环上的点(qcnt[i]>=n)就用dfs标记该负环上所有的点(负环上的点花费肯定小于3),可以使用spfa来解决。

    代码:

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #include<queue>
     5 #include<algorithm>
     6 using namespace std;
     7 const int N=2e2+5;
     8 const int INF=0x3f3f3f3f;
     9 
    10 int n;
    11 int dis[N],busy[N],qcnt[N],cost[N][N];
    12 bool vis[N],cir[N];
    13 
    14 //计算j,k两点间的收费 
    15 int cal_amt(int j,int i){
    16     return (busy[i]-busy[j])*(busy[i]-busy[j])*(busy[i]-busy[j]);
    17 }
    18 //标记所有x点能到达的点 
    19 void dfs(int x){
    20     cir[x]=true;
    21     for(int i=1;i<=n;i++){
    22         if(cost[x][i]==1&&!cir[i])
    23             dfs(i);
    24     }
    25 }
    26 
    27 bool spfa(int s){
    28     memset(dis,0x3f,sizeof(dis));
    29     memset(vis,false,sizeof(vis));
    30     memset(qcnt,0,sizeof(qcnt));
    31     dis[s]=0;
    32     queue<int>q;
    33     q.push(s);
    34     while(!q.empty()){
    35         int k=q.front();
    36         q.pop();
    37         vis[k]=false;
    38         for(int i=1;i<=n;i++){
    39             //跳过负环上的点
    40             if(i==k||cost[k][i]==-1||cir[i])
    41                 continue;
    42             if(dis[k]+cal_amt(k,i)<dis[i]){
    43                 dis[i]=dis[k]+cal_amt(k,i);
    44                 if(!vis[i]){
    45                     q.push(i);
    46                     qcnt[i]++;
    47                     //若存在负环,则dfs标记所有负环上的可达点
    48                     if(qcnt[i]>=n)
    49                         dfs(i);
    50                     vis[i]=true;
    51                 }
    52             }
    53         }
    54     }
    55 }
    56 
    57 int main(){
    58     int t,cas=0;
    59     scanf("%d",&t);
    60     while(t--){
    61         memset(cost,-1,sizeof(cost));
    62         memset(cir,false,sizeof(cir));
    63         scanf("%d",&n);
    64         for(int i=1;i<=n;i++){
    65             scanf("%d",&busy[i]);
    66         }
    67         int m;
    68         scanf("%d",&m);
    69         for(int i=1;i<=m;i++){
    70             int a,b;
    71             scanf("%d%d",&a,&b);
    72             cost[a][b]=1;
    73         }
    74         int q;
    75         scanf("%d",&q);
    76         spfa(1);
    77         printf("Case %d:
    ",++cas);
    78         for(int i=1;i<=q;i++){
    79             int des;
    80             scanf("%d",&des);
    81             //若该点在负环上、或者无法到达、或者收费小于3输出'?' 
    82             if(cir[des]||dis[des]==INF||dis[des]<3)
    83                 puts("?");
    84             else
    85                 printf("%d
    ",dis[des]);
    86         }
    87     }
    88     return 0;
    89 }
  • 相关阅读:
    ios9 之后 配置百度地图出现的错误
    While reading XXX pngcrush caught libpng error: N
    主题:Java WebService 简单实例
    win7下如何建立ftp服务器
    64.Minimum Path Sum
    63.Unique Path II
    62.Unique Paths
    32.Longest Valid Parenttheses
    105.Construct Binary Tree from Preorder and Inorder Traversal
    83.Remove Duplicates from Sorted List
  • 原文地址:https://www.cnblogs.com/fu3638/p/7881369.html
Copyright © 2011-2022 走看看