codeforces 287DIV2 E - Breaking Good(最短路)

来源:互联网 发布:如何查看软件源码 编辑:程序博客网 时间:2024/05/21 21:46

题意:

给你n个点和m条道路,1表示道路没问题,0表示道路正在修,选取一条1->n的最短路,其中不属于最短路中的没问题的道路需炸毁,最短路上的需要修的道路我们要修好

求1到n之间的造成影响最小的最短路中会被影响的道路


方法:

因为走一条没问题的道路是不会造成影响的,走有问题的道路的是有影响的,所以我们在找最短路的时候,找到走没问题的道路的最多那一条即可,用迪杰斯特拉+堆优化 或者SPFA都行


PS:当时以为要影响最小然后最短,没想到是最短然后影响最小,我写了一下迪杰斯特拉+堆优化 和SPFA 发现所花时间差不多


代码1:

#include <cstdio>#include <cstring>#include <cmath>#include <queue>#include <algorithm>using namespace std;#define maxm 200010#define maxn 100010#define INF 111111struct node{int a, b, c, next; node(){}node(int a, int b, int c, int d):a(a),b(b),c(c),next(d){}}edge[maxm];struct pp{int v, d1 ,d2;bool operator < (const pp &x) const{if(d1!= x.d1)return d1 > x.d1;return d2< x.d2;}};int n, m, tot;int head[maxn], vis[maxn];int dis[maxn], d[maxn], pre[maxn];int ans[maxn];priority_queue<pp> q;void add(int x, int y, int z){edge[++tot]= node(x, y, z, head[x]);head[x]= tot;}void Dij(){memset(d, 0, sizeof d);memset(vis, 0, sizeof vis);for(int i= 1; i< maxn; i++)dis[i]= INF;pp N;N.v= 1, N.d1= 0, N.d2= 0;q.push(N);while(!q.empty()){while(vis[N.v] && !q.empty()){N= q.top();q.pop();}if(vis[N.v])break;vis[N.v]= 1;dis[N.v]= N.d1;d[N.v]= N.d2;for(int i= head[N.v]; i!= -1; i= edge[i].next)if(!vis[edge[i].b]){if(dis[N.v]+1< dis[edge[i].b] || (dis[N.v]+1 == dis[edge[i].b] && d[N.v]+edge[i].c> d[edge[i].b])){pp M;M.v= edge[i].b;M.d1= dis[N.v]+1;M.d2= d[N.v]+edge[i].c;q.push(M);dis[edge[i].b]= M.d1;d[edge[i].b]= M.d2;pre[edge[i].b]= i;}}}memset(ans, 0, sizeof ans);int xx= n;while(xx!= 1){ans[(pre[xx]+1)/2]= 1;xx= edge[pre[xx]].a;}}int main(){while(scanf("%d %d",&n,&m)!=EOF){memset(head, -1, sizeof head);int x, y, z;tot= 0;int sum= 0;for(int i= 1; i<= m; i++){scanf("%d %d %d",&x,&y,&z);add(y, x, z);add(x, y, z);if(z)sum++;}Dij();printf("%d\n",sum+dis[n]-2*d[n]);for(int i= 2; i<= 2*m; i+=2)if(ans[i/2]^edge[i].c)printf("%d %d %d\n",edge[i].a,edge[i].b,edge[i].c^1);}return 0;}


代码2:

#include <cstdio>#include <cstring>#include <cmath>#include <queue>#include <algorithm>using namespace std;#define maxn 100010#define maxm 200010#define INF 111111struct node{int a,v, c, next;node(){}node(int a,int v, int c, int next):a(a),v(v), c(c), next(next){}}edge[maxm];struct pp{int v,d1,d2;};queue<int> q;int n, m, tot;int dis[maxn], d[maxn], pre[maxn], ans[maxn], head[maxn];int vis[maxn];void add(int x, int y, int z){edge[++tot]= node(x, y, z, head[x]);head[x]= tot;}void SPFA(){memset(d, 0, sizeof d);memset(ans, 0, sizeof ans);memset(vis, 0, sizeof vis);for(int i= 1; i<= maxn; i++)dis[i]= INF;dis[1]= 0;vis[1]= 1;q.push(1);while(!q.empty()){int v= q.front();q.pop();vis[v]= 0;for(int i= head[v]; i!= -1; i= edge[i].next)if(dis[v]+ 1 < dis[edge[i].v] || (dis[v]+1== dis[edge[i].v] && d[v]+ edge[i].c> d[edge[i].v])){dis[edge[i].v]= dis[v]+ 1;d[edge[i].v]= d[v]+ edge[i].c;pre[edge[i].v]= i;if(!vis[edge[i].v]){q.push(edge[i].v);vis[edge[i].v]= 1;}}}int xx= n;while(xx!= 1){ans[(pre[xx]+1)/2]= 1;xx= edge[pre[xx]].a;}}int main(){while(scanf("%d %d",&n,&m)!=EOF){tot= 0;int sum= 0, x, y, z;memset(head, -1, sizeof head);for(int i= 1; i<= m; i++){scanf("%d %d %d",&x,&y,&z);add(y, x, z);add(x, y, z);if(z) sum++;}SPFA();printf("%d\n",sum+dis[n]-2*d[n]);for(int i= 2; i<= 2*m; i+=2)if(ans[i/2]^edge[i].c)printf("%d %d %d\n",edge[i].a,edge[i].v,edge[i].c^1);}return 0;}


0 0
原创粉丝点击