您的位置:首页 > 其它

Codeforces 449B Jzzhu and Cities(最短路)

2017-03-05 20:30 267 查看
题目传送门:http://codeforces.com/contest/450/problem/D

题意:一个城市,有m条道路,还有k条铁路(铁路都与点1相连),问在不改变点1到各个点的最短路的前提下最多可以删除多少条铁路

思路:将道路和铁路一起建在同一个图中,跑一遍最短路并记录每个点的入度,接下来有两种情况可以判断可以删除这条铁路。

1,如果最短路比铁路到点1的距离短,那毫无疑问可以删除

2,如果最短路和铁路到点1的距离相同,那么如果入度大于1的话,说明可以通过走别的点到达,不需要铁路所以也可以删除

总结:

这道题一开始我是先用道路建的边,然后跑一边dijkstra,然后用铁路的长度和仅以道路构成的最短路去比较,判断是不是可以不用这条铁路。这样做,疯狂wa在第五个测试点,是因为忽略了某条铁路引来的某点最短路改变,会导致其他点的最短路可能也会随之而变,这样就不能仅仅用刚才道路跑出来的dijkstra来判断了。很伤......

AC代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5+5;
const int maxm = 800005;
const ll INF = 1e16;
struct Edge
{
int v, nxt;
ll w;
}edges[maxm];
struct HeapNode
{
int u;
ll d;
HeapNode(){}
HeapNode(int from, ll _distance):u(from), d(_distance){}
bool operator < (const HeapNode &other)const
{
return d > other.d;
}
};
bool vis[maxn];
struct Dijkstra
{
int n, head[maxn], eid;
ll dis[maxn], in[maxn];
void init(int n)
{
this->n = n;
eid = 0;
memset(head, -1, sizeof(head));
memset(in, 0, sizeof(in));
}
void AddEdge(int from, int to, ll w)
{
edges[eid].v = to;
edges[eid].w = w;
edges[eid].nxt = head[from];
head[from] = eid++;
}
void dijkstra(int s)
{
for(int i = 0; i <= n; i++)
dis[i] = INF;
priority_queue<HeapNode> q;
dis[s] = 0;
q.push(HeapNode(s, dis[s]));
while(!q.empty())
{
HeapNode now = q.top();
q.pop();
if(vis[now.u])
continue;
vis[now.u] = true;
int u = now.u;
for(int i = head[u]; i != -1; i = edges[i].nxt)
{
int v = edges[i].v;
if(dis[v] == dis[u] + edges[i].w)
in[v]++;
if(dis[v] > dis[u] + edges[i].w)
{
dis[v] = dis[u] + edges[i].w;
in[v] = 1;
q.push(HeapNode(v, dis[v]));
}
}
}
}
};
struct Train
{
int v;
ll dist;
}train[maxn];
int main()
{
int n, m, k;
while(cin >> n >> m >> k)
{
memset(vis, false, sizeof(vis));
Dijkstra dij;
dij.init(n);
for(int i = 0; i < m; i++)
{
int u, v;ll w;
scanf("%d%d%I64d", &u, &v, &w);
dij.AddEdge(u, v, w);
dij.AddEdge(v, u, w);
}
for(int i = 0; i < k; i++)
{
int v;ll w;
scanf("%d%I64d", &v, &w);
train[i].v = v;
train[i].dist = w;
dij.AddEdge(1, v, w);
}
dij.dijkstra(1);
ll ans = 0;
for(int i = 0; i < k; i++)
{
if(train[i].dist == dij.dis[train[i].v])
if(dij.in[train[i].v] > 1)
{
ans++;
dij.in[train[i].v]--;
}
if(train[i].dist > dij.dis[train[i].v])
ans++;
}
printf("%I64d\n", ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: