D. Jzzhu and Cities
题意:n个城市,首都在城市1,城市之间有n条公路和k条铁路(铁路一端必为首都)连接。问最多能够撤掉多少条铁路,使得首都到所有城市的最短路不增加。
思路:这个题我用了各种方法,比如先用公路求最短路,然后贪心加入铁路,不是WA就是TLE。。然后看了别人的题解,方法是跑一遍最短路(优先选择公路),记录每个点的前驱边,统计有多少条边是铁路。
#include <iostream>
#include <stdio.h>
#include <string>
#include <map>
#include <vector>
#include <stack>
#include <queue>
#include <string.h>
#include <algorithm>
using namespace std;
#define ll long long
const int MAXN=200010;
const ll INF=200000000000010LL;
struct Edge{
int v;
int len;
bool type;
Edge(int v,int len,bool type):v(v),len(len),type(type){
}
Edge(){
}
}edge[800010];
struct Node{
int u;
ll d;
bool operator<(const Node& n)const{
return d>n.d;
}
Node(int u,int d):u(u),d(d){
}
};
ll dist[MAXN];
int pre[MAXN];
int head[400010];
int next[800010];
bool vis[MAXN];
void bfs(int s,int dis){
priority_queue<Node> que;
que.push(Node(s,dis));
dist[s]=dis;
while(!que.empty()){
Node cur=que.top(); que.pop();
if(vis[cur.u])continue;
vis[cur.u]=1;
for(int i=head[cur.u];~i;i=next[i]){
if(dist[cur.u]+edge[i].len<dist[edge[i].v]){
dist[edge[i].v]=dist[cur.u]+edge[i].len;
que.push(Node(edge[i].v,dist[cur.u]+edge[i].len));
pre[edge[i].v]=i;
}else if(dist[cur.u]+edge[i].len==dist[edge[i].v]&&dist[edge[i].v]){
pre[edge[i].v]=i;
}
}
}
}
int pos;
void addedge(int u,int v,int w,int type){
edge[pos]=Edge(v,w,type);
next[pos]=head[u];
head[u]=pos++;
}
int main(){
memset(head,-1,sizeof(head));
pos=0;
int n,m,k;
cin>>n>>m>>k;
for(int i=1;i<=n;i++)dist[i]=INF;
for(int i=0;i<m;i++){
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
addedge(u,v,w,0);
addedge(v,u,w,0);
}
for(int i=0;i<k;i++){
int v,w;
scanf("%d%d",&v,&w);
addedge(1,v,w,1);
}
int ans=0;
bfs(1,0);
for(int i=2;i<=n;i++){
ans+=edge[pre[i]].type;
}
ans=k-ans;
cout<<ans<<endl;
return 0;
}