博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
hdu3873 有约束条件的最短路
阅读量:4985 次
发布时间:2019-06-12

本文共 2913 字,大约阅读时间需要 9 分钟。

题目大意:美国佬打算入侵火星,火星上有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 
2 #include
3 #include
4 #include
5 #include
6 #include
7 #include
8 #include
9 #include
10 #include
11 #include
12 #include
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
g[3000 + 10]; 29 vector
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
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\n", dist[n]);128 }129 return 0;130 }
View Code

 

转载于:https://www.cnblogs.com/justPassBy/p/4506837.html

你可能感兴趣的文章
LeetCode 445——两数相加 II
查看>>
预备作业03 20162308马平川
查看>>
【Java】嵌套For循环性能优化案例
查看>>
面试了一个开发人员
查看>>
软件工程及软件项目开发流程
查看>>
关于android4.3 bluetooth4.0的那些事儿
查看>>
嵌入式成长轨迹14 【嵌入式环境及基础】【Linux下的C编程 上】【gcc、gdb和GNU Make】...
查看>>
C语言讲义——变量的输出
查看>>
shell脚本 ----每天学一点shell
查看>>
FZU2150 :Fire Game (双起点BFS)
查看>>
php_常用操作_读取文件_数据库操作
查看>>
Linux中GCC源码编译安装
查看>>
equals与==关于Object覆盖和重载问题
查看>>
KVO
查看>>
js基础教程四之无缝滚动
查看>>
关于C51 keil使用中.c文件的链接心得
查看>>
Ios 弹框 MJPopup,KxMenu
查看>>
ssh框架添加时添加不到数据库问题
查看>>
解决AR中Receivable Activities 运行不了的问题
查看>>
SQL SERVER 如何处理带字母的自增列--【叶子】
查看>>