zoukankan      html  css  js  c++  java
  • Hdu 5385 The path

    题目链接:

      Hdu 5385 The path

    题目描述:

      给出一个有向图,有n个点,m条边。假设从1到x点的最短路的值用d(x),要求给每条边赋一个[1,n]边权值后,存在一个y属于[1,n]使得:d(1)<d(2)<d(3)...d(y-1)<d(y)>d(y+1)...d(n-1)>d(n),输出任意一种赋值方案。

    解题思路:

      因为分配好边权以后要满足这个式子:d(1)<d(2)<d(3)...d(y-1)<d(y)>d(y+1)...d(n-1)>d(n)。又因为在用prim求最小生成树的时候,向生成树上加点的顺序就满足:最先加入的点到树根的距离最短。然后我们就根据这个性质每次向生成树上加点就好了。每次加点要么加编号最小的,要么加编号最大的,并且记录加入时间,最后在生成树上的边权值为两端点加入时间之差,不在生成树上的边权值记为n即可。

      比赛的时候感觉这个题目炒鸡高大上,想到套用各种算法,看了题解感觉自己蠢哭了好嘛?现在写题解呢,我竟然不知道要把这个题目分类到哪里合适了。

     1 #include <cmath>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <iostream>
     5 #include <algorithm>
     6 using namespace std;
     7 
     8 const int maxn = 100005;
     9 struct node
    10 {
    11     int to, next, id;
    12 } edge[maxn];
    13 
    14 struct Node
    15 {
    16     int l, r;
    17 } p[maxn];
    18 int tot, head[maxn], dis[maxn];
    19 bool vis[maxn], ans[maxn];
    20 
    21 void init ()
    22 {
    23     tot = 0;
    24     memset (head, -1, sizeof(head));
    25     memset (ans, false, sizeof(ans));
    26     memset (dis, 0, sizeof(dis));
    27     memset (vis, false, sizeof(vis));
    28 }
    29 
    30 void Add (int from, int to, int id)
    31 {
    32     edge[tot].to = to;
    33     edge[tot].id = id;
    34     edge[tot].next = head[from];
    35     head[from] = tot++;
    36 }
    37 
    38 void solve (int u, int time)
    39 {
    40     dis[u] = time;
    41     for (int i=head[u]; i!=-1; i=edge[i].next)
    42     {
    43         int v = edge[i].to;
    44         if (vis[v])
    45             continue;
    46         vis[v] = true;
    47         ans[edge[i].id] = true;
    48     }
    49 }
    50 
    51 int main ()
    52 {
    53     int t, n, m;
    54     scanf ("%d", &t);
    55     while (t --)
    56     {
    57         init ();
    58         scanf ("%d %d", &n, &m);
    59         
    60         for (int i=1; i<=m; i++)
    61         {
    62             scanf ("%d %d", &p[i].l, &p[i].r);
    63             Add (p[i].l, p[i].r, i);
    64         }
    65         
    66         int s = 1, e = n, x = 0;
    67         vis[s] = true;
    68         
    69         while (s <= e)
    70         {
    71             if (vis[s])
    72                 solve (s++, x++);
    73             if (vis[e])
    74                 solve (e--, x++);
    75         }
    76         
    77         for (int i=1; i<=m; i++)
    78             if (ans[i])
    79                 printf ("%d
    ", abs(dis[p[i].l] - dis[p[i].r]));
    80             else
    81                 printf ("%d
    ", n);
    82                 
    83     }
    84     return 0;
    85 }
    本文为博主原创文章,未经博主允许不得转载。
  • 相关阅读:
    Linq基础知识小记四之操作EF
    EF基础知识小记一
    Linq基础知识小记三
    Linq基础知识之延迟执行
    Linq基础知识小记二
    Linq基础知识小记一
    EF 通过DataAnnotations配置属性和类型
    C# 引用类型和值类型
    算法练习之环形链表
    C1128节数超过对象文件格式限制: 请使用 /bigobj 进行编译
  • 原文地址:https://www.cnblogs.com/alihenaixiao/p/4730634.html
Copyright © 2011-2022 走看看