• Constructing Roads(SPFA+邻接表)


    题目描述

        Long long ago, There was a country named X, the country has N cities which are numbered from 1 to N.
        The king of Country-X wants to construct some roads.
        Please note that Country-X is blessed by an angel. He(The angel is a boy? This is no science, but do not care about those details, this angel is so cute, he must be a boy) can use magic to make one road connections directly from two cities’ cost to be half, but the magic can only be used once.
        The king wants to know the minimal cost to construct a road between City-A and City-B. Because of there are so many cities and roads, the construction division comes to you, the only programmer he knows, for help.
    You should write a program to calculate the minimal cost between City-A and City-B to help him.

    输入

        There are multiple test cases.
        For each test case:
        The fist line is two integers N and M (2 <= N <= 10000 <= M <= 50000)
        Each of the following M lines contains three integers UV and W (1<= U,V<= N, 0 <= <= 1000) . It shows that if we construct a road between the U-th city and the V-th city , the cost is W.
        The next line is two integers A and B (1<= A, B <= N).

    输出

        For each test case,output one line containing the minimal cost , if there is no route from A to B , the output should contain the string “No solution” (without the quotes).

    示例输入

    2 1
    1 2 99
    1 2
    4 3
    1 2 312
    2 3 520
    3 1 999
    3 4

    示例输出

    49
    No solution

    题意:给m条边,求出s到t的最短路径,其中有一条边的权值可以减半。
    思路:两次SPFA,再穷举每一条边,让其减半,最后比较得住最小权值。
     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<queue>
     4 using namespace std;
     5 
     6 const int maxn = 1100;
     7 const int INF = 0x3f3f3f3f;
     8 struct node
     9 {
    10     int u,v,w;
    11     int next;
    12 }edge[500100];
    13 int n,m,cnt;
    14 int p[500100];
    15 int dis[2][maxn];//dis[0][i]表示起点到所有点的最短路,dis[1][i]表示终点到所有点的最短路。
    16 int inque[maxn];
    17 
    18 void add(int u, int v, int w)
    19 {
    20     edge[cnt].u = u;
    21     edge[cnt].v = v;
    22     edge[cnt].w = w;
    23     edge[cnt].next = p[u];
    24     p[u] = cnt;
    25     cnt++;
    26 }
    27 void spfa(int s, int f)
    28 {
    29     queue<int>que;
    30     while(!que.empty())
    31         que.pop();
    32     memset(inque,0,sizeof(inque));
    33     for(int i = 1; i <= n; i++)
    34         dis[f][i] = INF;
    35 
    36     que.push(s);
    37     inque[s] = 1;
    38     dis[f][s] = 0;
    39 
    40     while(!que.empty())
    41     {
    42         int u = que.front();
    43         que.pop();
    44         inque[u] = 0;
    45 
    46         for(int i = p[u]; i; i = edge[i].next)
    47         {
    48             if(dis[f][edge[i].v] > dis[f][u] + edge[i].w)
    49             {
    50                 dis[f][edge[i].v] = dis[f][u] + edge[i].w;
    51                 if(!inque[edge[i].v])
    52                 {
    53                     inque[edge[i].v] = 1;
    54                     que.push(edge[i].v);
    55                 }
    56             }
    57         }
    58     }
    59 }
    60 
    61 int main()
    62 {
    63     //freopen("data1.in","r",stdin);
    64     //freopen("c.txt","w",stdout);
    65     while(~scanf("%d %d",&n,&m))
    66     {
    67         int u,v,w;
    68         cnt = 0;
    69         memset(p,0,sizeof(p));//前项星
    70         for(int i = 0; i < m; i++)
    71         {
    72             scanf("%d %d %d",&u,&v,&w);
    73             add(u,v,w);
    74             add(v,u,w);
    75         }
    76         int s,t;
    77         scanf("%d %d",&s,&t);
    78         spfa(s,0);
    79         spfa(t,1);
    80         int ans = INF;
    81         for(int i = 0; i < cnt; i++)
    82         {
    83             u = edge[i].u;
    84             v = edge[i].v;
    85             w = edge[i].w;
    86             int d = dis[0][u] + dis[1][v] + w/2;
    87             if(ans > d)
    88                 ans = d;
    89         }
    90         if(ans >= INF)
    91             printf("No solution
    ");
    92         else printf("%d
    ",ans);
    93     }
    94     return 0;
    95 }
    View Code
  • 相关阅读:
    AcWing 286. 选课
    背包问题极小值空间至少是j
    Logo在线公式编辑转图片
    AcWing 1055. 股票买卖 II
    枚举一个集合的所有有效子集
    CF580D Kefa and Dishes [洛谷]
    AcWing 1282. 搜索关键词
    背包问题最大值空间恰好是j
    多叉树转二叉树有依赖的背包问题解法
    Thinkpad T14重装Win10后不见无线网络问题的解决
  • 原文地址:https://www.cnblogs.com/LK1994/p/3438125.html
Copyright © 2020-2023  润新知