codeforces 449B Jzzhu and Cities (Dij+堆优化)

输入一个无向图<V,E>    V<=1e5, E<=3e5

现在另外给k条边(u=1,v=s[k],w=y[k])

问在不影响从结点1出发到所有结点的最短路的前提下,最多可以删除k条边的多少条

跑最短路的时候维护或者统计就好了

一开始用spfa.然后TLE 45...好久没写  Dij+堆优化   ...

p.s.优先队列默认大顶堆

Dij+堆优化   264ms

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #include <algorithm>
 5 #include <cmath>
 6 #include <queue>
 7 #include <set>
 8 #include <string>
 9 using namespace std;
10 
11 #define ll long long
12 #define maxn 100010
13 #define maxm 700010
14 
15 int head[maxn];
16 struct edge{
17     int v,w,nxt;
18 }e[maxm];
19 int E;
20 void init(){E=0;memset(head,-1,sizeof(head));}
21 void addedge(int u,int v,int w){
22     e[E].v=v,e[E].w=w,e[E].nxt=head[u];
23     head[u]=E++;
24 }
25 priority_queue<pair<ll,int> >que;
26 bool vis[maxn];
27 //ll d[maxn];
28 int main(){
29     int n,m,k;
30     while(~scanf("%d%d%d",&n,&m,&k)){
31         init();
32         for(int i=0;i<m;++i){
33             int u,v,w;
34             scanf("%d%d%d",&u,&v,&w);
35             addedge(u,v,w);
36             addedge(v,u,w);
37         }
38         que.push(make_pair(0ll,1));
39         for(int i=0;i<k;++i){
40             int s,y;
41             scanf("%d%d",&s,&y);
42             que.push(make_pair(0ll-y,-s));
43         }
44         memset(vis,false,sizeof(vis));
45         int ans=0;
46         while(!que.empty()){
47             pair<ll,int> tmp = que.top();que.pop();
48             ll dis = -tmp.first;
49             int u = tmp.second;
50             if(u<0){
51                 u=-u;
52                 if(vis[u])++ans;
53             }
54             if(vis[u]) continue;
55             vis[u]=true;
56             //d[u] = dis;
57             for(int i=head[u];i!=-1;i=e[i].nxt)
58                 if(vis[e[i].v]==false)
59                     que.push(make_pair( -dis-e[i].w, e[i].v));
60         }
61         printf("%d
",ans);
62     }
63     return 0;
64 }
View Code

spfa  TLE 45

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #include <algorithm>
 5 #include <cmath>
 6 #include <queue>
 7 #include <set>
 8 #include <string>
 9 using namespace std;
10 
11 #define ll long long
12 #define maxn 100010
13 #define maxm 700010
14 
15 int head[maxn];
16 struct edge{
17     int v,w,nxt;
18     int k;
19 }e[maxm];
20 int E;
21 void init(){E=0;memset(head,-1,sizeof(head));}
22 void addedge(int u,int v,int w,int kind){
23     e[E].v=v,e[E].w=w,e[E].nxt=head[u];
24     e[E].k = kind;
25     head[u]=E++;
26 }
27 int q[maxn];
28 bool inq[maxn];
29 bool bus[maxn];
30 ll dis[maxn];
31 void spfa(){
32     int hd=0,tl=0;
33     q[tl++]=1;
34     memset(dis,0x3f,sizeof(dis));
35     dis[1]=0;
36     memset(inq,false,sizeof(inq));
37     inq[1]=true;
38     memset(bus,false,sizeof(bus));
39     while(hd!=tl){
40         int u = q[hd++];
41         if(hd==maxn)hd=0;
42         inq[u] = false;
43         for(int i=head[u];i!=-1;i=e[i].nxt){
44             int v = e[i].v, w = e[i].w, k = e[i].k;
45             if(dis[u]+w < dis[v]){
46                 dis[v] = dis[u]+w;
47                 bus[v] = false;
48                 if(k==0) bus[v]=true;
49                 if(inq[v]==false){
50                     inq[v]=true;
51                     q[tl++]=v;
52                     if(tl==maxn)tl=0;
53                 }
54             }else if(dis[u]+w == dis[v]){
55                 if(k==0) bus[v]=true;
56             }
57         }
58     }
59 }
60 int si[100010],yi[100010];
61 int main(){
62     int n,m,k;
63     while(~scanf("%d%d%d",&n,&m,&k)){
64         init();
65         for(int i=0;i<m;++i){
66             int u,v,w;
67             scanf("%d%d%d",&u,&v,&w);
68             addedge(u,v,w,0);
69             addedge(v,u,w,0);
70         }
71         for(int i=0;i<k;++i){
72             scanf("%d%d",si+i,yi+i);
73             addedge(1,si[i],yi[i],1);
74         }
75         spfa();
76         int ans=0;
77         for(int i=0;i<k;++i){
78             int v = si[i];
79             if(dis[v] < yi[i]) ++ans;
80             else {
81                 if(bus[v]==false)bus[v]=true;
82                 else ++ans;
83             }
84         }
85         printf("%d
",ans);
86     }
87     return 0;
88 }
View Code
原文地址:https://www.cnblogs.com/nextbin/p/3859043.html