传送门
这道题和hdu2680几乎一样.
// 题意: 就是给定一幅有向图(n, k), 有m个人, 给出终点ed. 给出那m个人所在的城市编号和他们行驶速度, 问最小到ed的是哪个编号, 如果时间相等取距离终点远的那个点, 再相等取编号大的那个人.
// 思路: 很明显的反向建图, 以终点做起点跑最短路, 然后扫一遍比较他们的时间和距离就行啦~
注意: 题中说for each case , 所以是多case !!! 我这wa了一发.
AC Code
const int maxm = 5e3 + 5;
int cas=1;
int cnt, head[maxn];
struct node
{
int to, next, w;
bool operator < (const node& a) const {
return w > a.w;
}
} e[maxm];
void add(int u, int v, int w) {
e[cnt] = (node){v, head[u], w};
head[u] = cnt++;
}
void init() {
cnt = 0;
memset(head, -1, sizeof(head));
}
bool vis[maxn];
int dis[maxn];
void dij(int st,int ed)
{
priority_queue q;
Fill(dis,inf); Fill(vis,0);
dis[st] = 0;
q.push((node){st, 0, 0});
while (!q.empty()) {
node u = q.top();
q.pop();
if(vis[u.to]) continue;
vis[u.to] = 1;
for (int i = head[u.to]; ~i; i = e[i].next) {
node k = e[i];
if (dis[k.to] > dis[u.to] + k.w) {
dis[k.to] = dis[u.to] + k.w;
q.push((node){k.to, 0, dis[k.to]});
}
}
}
}
int p[maxn], v[maxn];
void solve() {
int n, m, k;
while(~scanf("%d%d%d", &n, &m, &k)) {
init();
for (int i = 1 ; i <= k ; i ++) {
int u , v, w;
scanf("%d%d%d", &u, &v, &w);
add(v, u, w);
}
int st; scanf("%d", &st);
for (int i = 1 ; i <= m ; i ++) {
scanf("%d", &p[i]);
}
for (int i = 1 ; i <= m ; i ++) {
scanf("%d", &v[i]);
}
dij(st, -1);
db tt = db(inf); int dd = 0, id = -1;
for (int i = m ; i >= 1 ; i --) {
if (dis[p[i]] == inf) continue;
if (tt > 1.0*dis[p[i]]/v[i]) {
tt = 1.0*dis[p[i]]/v[i];
dd = dis[p[i]];
id = i;
}
else if (tt == 1.0*dis[p[i]]/v[i] && dis[p[i]] > dd) {
dd = dis[p[i]];
id = i;
}
}
if (id == -1) cout << "No one" << endl;
else cout << id << endl;
}
}