• hdu3873 有约束条件的最短路


    题目大意:美国佬打算入侵火星,火星上有n个城市,有些城市可能受其他城市保护,

    如果i城市受j城市保护,那么你必须先攻占j城市才能再攻占i城市,问你攻占城市n的最短时间是多少。

    数据解释:

    给定t, 表示有t组数据

    给定n,m 表示n个点,m条边

    接下来m条有向边, a,b,c  表示从a到b,距离为c

    接下来n行, 每行第一个整数d,然后接下来是d个整数,x1,x2,...xd, 表示第i个城市受d个城市保护,表示只有城市x1,x2...xd都被攻占,城市i才能被攻占

    问从点1到达点n的最短时间(一定是可达的)

    重要的一点是,因为是军队,所以可以同时进军多个点。

    思路:

    如果城市i受其他城市保护, 那么攻占城市i的最短时间是从1-->i和攻占城市i的保护城市  这两个时间中的最大值。

    设dist[i] 为 攻占城市i的最短时间,  maxn[i] 为攻占所有保护i的城市中时间最长的那个

    那么 dist[i] = max(dist[i],maxn[i])

      1 #include <stdio.h>
      2 #include <string.h>
      3 #include <stdlib.h>
      4 #include <algorithm>
      5 #include <iostream>
      6 #include <queue>
      7 #include <stack>
      8 #include <vector>
      9 #include <map>
     10 #include <set>
     11 #include <string>
     12 #include <math.h>
     13 using namespace std;
     14 #pragma warning(disable:4996)
     15 typedef long long LL;
     16 const int INF = 1 << 30;
     17 /*
     18 
     19 */
     20 struct Edge
     21 {
     22     int to, dist;
     23     bool operator<(const Edge&rhs)const
     24     {
     25         return dist > rhs.dist;
     26     }
     27 };
     28 vector<Edge> g[3000 + 10];
     29 vector<int> pro[3000 + 10];
     30 bool vis[3000 + 10];
     31 int protect[3000 + 10];
     32 int dist[3000 + 10], maxn[3000 + 10], ans[3000 + 10];
     33 void dij(int n)
     34 {
     35     for (int i = 1; i <= n; ++i)
     36     {
     37         vis[i] = false;
     38         dist[i] = INF;
     39         maxn[i] = 0;
     40     }
     41     dist[1] = 0;
     42     priority_queue<Edge> q;
     43     Edge cur, tmp;
     44     cur.to = 1;
     45     cur.dist = 0;
     46     q.push(cur);
     47     while (!q.empty())
     48     {
     49         cur = q.top(); q.pop();
     50         int x = cur.to;
     51         if (vis[x]) continue;
     52         for (int i = 0; i < pro[x].size(); ++i)
     53         {
     54             int v = pro[x][i];
     55             maxn[v] = max(maxn[v], dist[x]);//求出到达保护城市v的城市最长的那一个
     56             protect[v]--;
     57         }
     58         vis[x] = true;
     59         for (int i = 0; i < g[x].size(); ++i)
     60         {
     61             int v = g[x][i].to;
     62             if (dist[v] > dist[x] + g[x][i].dist)
     63                 dist[v] = dist[x] + g[x][i].dist;
     64         }
     65         for (int i = 1; i <= n; ++i)
     66         {
     67             if (vis[i]) continue;
     68             dist[i] = max(dist[i], maxn[i]);
     69             if (protect[i] == 0 && dist[i]!=INF)//在点i没有解除约束之前,我们不能让它去更新其它的点
     70             {
     71                 tmp.to = i;
     72                 tmp.dist = dist[i];
     73                 q.push(tmp);
     74             }
     75             
     76         }
     77     }
     78 }
     79 
     80 void input(int &x)
     81 {
     82     char ch = getchar();
     83     while (ch > '9' || ch < '0')
     84         ch = getchar();
     85     x = 0;
     86     while (ch >= '0' && ch <= '9')
     87     {
     88         x = x * 10 + ch - '0';
     89         ch = getchar();
     90     }
     91 }
     92 int main()
     93 {
     94     int t, n, m, i, a, b, c;
     95     Edge tmp;
     96     scanf("%d", &t);
     97     while (t--)
     98     {
     99         //scanf("%d%d", &n, &m);
    100         input(n); input(m);
    101         for (i = 1; i <= n; ++i)
    102         {
    103             g[i].clear();
    104             pro[i].clear();
    105         }
    106         for (i = 0; i < m; ++i)
    107         {
    108             //scanf("%d%d%d", &a, &b, &c);
    109             input(a); input(b); input(c);
    110             tmp.to = b;
    111             tmp.dist = c;
    112             g[a].push_back(tmp);
    113         }
    114         for (int i = 1; i <= n; ++i)
    115         {
    116             //scanf("%d", &a);
    117             input(a);
    118             protect[i] = a;
    119             for (int j = 0; j < a; ++j)
    120             {
    121                 //scanf("%d", &b);
    122                 input(b);
    123                 pro[b].push_back(i);
    124             }
    125         }
    126         dij(n);
    127         printf("%d
    ", dist[n]);
    128     }
    129     return 0;
    130 }
    View Code
  • 相关阅读:
    文件上传Web小案例
    加密方法(MD5加密)
    解决中文乱码(不可能解决不了)
    jquery的一些常见使用方法
    Ajax的作用
    日期时间格式的转换
    前端点击复制内容
    uniapp 移动端防止点击事件穿透
    getCurrentPages 获取当前网页完整的URL
    关闭微信浏览器网页
  • 原文地址:https://www.cnblogs.com/justPassBy/p/4506837.html
Copyright © 2020-2023  润新知