题目大意:美国佬打算入侵火星,火星上有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])

 #include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <algorithm>
#include <iostream>
#include <queue>
#include <stack>
#include <vector>
#include <map>
#include <set>
#include <string>
#include <math.h>
using namespace std;
#pragma warning(disable:4996)
typedef long long LL;
const int INF = << ;
/* */
struct Edge
{
int to, dist;
bool operator<(const Edge&rhs)const
{
return dist > rhs.dist;
}
};
vector<Edge> g[ + ];
vector<int> pro[ + ];
bool vis[ + ];
int protect[ + ];
int dist[ + ], maxn[ + ], ans[ + ];
void dij(int n)
{
for (int i = ; i <= n; ++i)
{
vis[i] = false;
dist[i] = INF;
maxn[i] = ;
}
dist[] = ;
priority_queue<Edge> q;
Edge cur, tmp;
cur.to = ;
cur.dist = ;
q.push(cur);
while (!q.empty())
{
cur = q.top(); q.pop();
int x = cur.to;
if (vis[x]) continue;
for (int i = ; i < pro[x].size(); ++i)
{
int v = pro[x][i];
maxn[v] = max(maxn[v], dist[x]);//求出到达保护城市v的城市最长的那一个
protect[v]--;
}
vis[x] = true;
for (int i = ; i < g[x].size(); ++i)
{
int v = g[x][i].to;
if (dist[v] > dist[x] + g[x][i].dist)
dist[v] = dist[x] + g[x][i].dist;
}
for (int i = ; i <= n; ++i)
{
if (vis[i]) continue;
dist[i] = max(dist[i], maxn[i]);
if (protect[i] == && dist[i]!=INF)//在点i没有解除约束之前,我们不能让它去更新其它的点
{
tmp.to = i;
tmp.dist = dist[i];
q.push(tmp);
} }
}
} void input(int &x)
{
char ch = getchar();
while (ch > '' || ch < '')
ch = getchar();
x = ;
while (ch >= '' && ch <= '')
{
x = x * + ch - '';
ch = getchar();
}
}
int main()
{
int t, n, m, i, a, b, c;
Edge tmp;
scanf("%d", &t);
while (t--)
{
//scanf("%d%d", &n, &m);
input(n); input(m);
for (i = ; i <= n; ++i)
{
g[i].clear();
pro[i].clear();
}
for (i = ; i < m; ++i)
{
//scanf("%d%d%d", &a, &b, &c);
input(a); input(b); input(c);
tmp.to = b;
tmp.dist = c;
g[a].push_back(tmp);
}
for (int i = ; i <= n; ++i)
{
//scanf("%d", &a);
input(a);
protect[i] = a;
for (int j = ; j < a; ++j)
{
//scanf("%d", &b);
input(b);
pro[b].push_back(i);
}
}
dij(n);
printf("%d\n", dist[n]);
}
return ;
}

hdu3873 有约束条件的最短路的更多相关文章

  1. poj 1724 最短路+优先队列(两个约束条件)

    /*两个约束条件求最短路,用优先队列*/ #include<stdio.h> #include<string.h> #include<queue> using na ...

  2. hdu3873 Invade the Mars 有限制的最短路

    此段略过.看完题目,觉得这真的是一道好题目.自己有想法,但是实现起来却很难.看题解,写代码,然后写题解,意义何在?我不认为自己总是这么弱.就算抄代码,我也要有自己的理解.菜鸟总会成长. 首先,题目必须 ...

  3. POJ 1201 Intervals (差分约束,最短路)

    题意: 有一个集合Z,其元素都是整整数,但是数量未知.现有n个约束,形如 [a,b]=c 表示整数区间[a,b]中有c个元素在Z中出现.问集合Z最小可能含多少个元素? 思路: 对于所给的区间 cnt[ ...

  4. 【UVA11478】Halum (最短路解差分约束)

    题目: Sample Input2 11 2 102 11 2 -103 31 2 42 3 23 1 54 52 3 44 2 53 4 23 1 01 2 -1Sample OutputInfin ...

  5. [HAOI2005]路由问题,第二短路

    [问题描写叙述]     X城有一个含有N个节点的通信网络,在通信中,我们往往关心信息从一个节点I传输到节点J的最短路径.遗憾的是.因为种种原因,线路中总有一些节点会出故障,因此在传输中要避开故障节点 ...

  6. 【NOIP复习】最短路总结

    [模板] /*堆优化Dijkstra*/ void dijkstra() { priority_queue<pair<ll,int>,vector<pair<ll,int ...

  7. HAOI 2005 路由选择问题 (最短路+次短路)

    问题描述 X城有一个含有N个节点的通信网络,在通信中,我们往往关心信息从一个节点I传输到节点J的最短路径.遗憾的是,由于种种原因,线路中总有一些节点会出故障,因此在传输中要避开故障节点. 任务一:在己 ...

  8. 培训补坑(day1:最短路&two-sat)

    经过12天的滚粗,终于迎来了暑期培训的结尾啦QAQ 结业考才考了90分,真是对不起孙爷(孙爷请收下我的膝盖) orz小粉兔怒D rank 1 获得小粉兔一只QAQ 由于这次12天的培训题目又比较多,算 ...

  9. 最短路 & 差分约束 总结

     一.引例      1.一类不等式组的解 二.最短路       1.Dijkstra       2.图的存储       3.链式前向星       4.Dijkstra + 优先队列      ...

随机推荐

  1. mysql iot 主键自增列问题

    mysql 如何避免热点块? 主键按sn自增列 Oracle 可以通过翻转索引 比如 插入101 102 103 104 变成101 201 301 401 分散数据 反转索引坏处,无法index r ...

  2. [置顶] 关于redhat系统yum源的配置1

    安装过Linux软件的用户就知道,有时我们安装一个软件,需要依赖其他软件,所以必需找全所有的软件,这是一个极其麻烦的事情,有没什么方式可以让它自己去找依赖呢? 答案当然是肯定,这就需要我们配置一个神器 ...

  3. Linux入门基础#2:Linux文件系统基本结构

    本文出自   http://blog.csdn.net/shuangde800 ------------------------------------------------------------ ...

  4. Androidclient推断server是否开启 HttpHostException解决方式

    Android推断服务器是否开启,试了非常多方法都不行(若server未开启会卡在HttpResponse那),有人说高版本号的Android程序不同意在主线程中訪问网络(主线程中能够读写网络流)有待 ...

  5. Swift 编程语言新手教程

    今天在网上看到一篇很好的教程,分享给大家 原文地址:http://gashero.iteye.com/blog/2075324 文件夹 1   简单介绍 2   Swift入门 3   简单值 4   ...

  6. Android获取设备採用的时间制式(12小时制式或24小时制式)

    /** * 获取设备採用的时间制式(12小时制式或者24小时制式) * 注意: * 在模拟器上获取的时间制式为空 */ private void getTime_12_24(Context conte ...

  7. Objective-C中经常使用的结构体NSRange,NSPoint,NSSize(CGSize),NSRect

    Objective-C中经常使用的结构体NSRange,NSPoint,NSSize(CGSize),NSRect 1   NSRange NSRange 的原型为 typedef struct _N ...

  8. C#验证字符串是否是数字,是否包括中文,是否是邮箱格式,是否是电话格式

    using System;     using System.Web;     using System.Text;     using System.Web.UI.WebControls;     ...

  9. Free Mind » Blog Archive » Yakuake + dtach vs Screen + urxvt

    Free Mind » Blog Archive » Yakuake + dtach vs Screen + urxvt Yakuake + dtach vs Screen + urxvt

  10. 用C语言写解释器(一)——我们的目标

    声明 为提高教学质量,我所在的学院正在筹划编写C语言教材.<用C语言写解释器>系列文章经整理后将收入书中"综合实验"一章.因此该系列的文章主要阅读对象定为刚学完C语言的 ...