【CF 507E】Breaking Good
来源:互联网 发布:淘宝网女式运动服 编辑:程序博客网 时间:2024/06/10 04:05
【CF 507E】Breaking Good
双条件最短路
每个路有已搭建和未搭建两种状态 需要把经过的路都建起 为经过的路都拆掉
优先经过最少条路 同样少的路走改动(搭建+拆掉)最小的
最短路跑完后把最短的路上的路径标记一下
bfs输出拆除和搭建 在最短路径上的路 未建的搭建 不在的建好的拆掉
通过此题试了一下spfa的一个小优化还有dijkstra的优先队列优化
不过别看spfa加优化快了点 前两天做了个专门卡这个优化的题……想方设法让他多跑就是。。HDOJ 4889 有兴趣的可以去瞅瞅
此题代码如下:
//spfa 109ms#include <iostream>#include <cstdio>#include <cstring>#include <queue>#define sz 100000#define INF 0x3f3f3f3fusing namespace std;typedef struct Edge//邻接表建图{ int v,next,hs; int in;}Edge;bool vis[sz+1];Edge eg[2*sz+2];int head[sz+1];int rep[sz+1],dis[sz+1],site[sz+1],pre[sz+1];//rep重建路数 dis经过路数 site当前点与前驱点间路下标 用以标记 pre前驱int alb,n,m,tp;void Add(int u,int v,int w){ eg[tp].v = v; eg[tp].hs = w; eg[tp].next = head[u]; eg[tp].in = 0; head[u] = tp++;}void spfa(){ queue <int> q; memset(vis,0,sizeof(vis)); memset(dis,INF,sizeof(dis)); memset(rep,INF,sizeof(rep)); int i,u,v,p,ned; q.push(1); dis[1] = rep[1] = 0; pre[1] = vis[1] = 1; while(!q.empty()) { u = q.front(); q.pop(); if(u == n) return; for(i = head[u]; i != -1; i = eg[i].next) { ned = eg[i].hs^1; v = eg[i].v; if(dis[u]+1 < dis[v] || (dis[u]+1 == dis[v] && rep[u] + ned < rep[v])) { site[v] = i; pre[v] = u; dis[v] = dis[u]+1; rep[v] = rep[u] + ned; if(!vis[v]) { q.push(v); vis[v] = 1; } } } }}void Bfs(){ memset(vis,0,sizeof(vis)); queue <int> q; q.push(1); int i,u,v; vis[1] = 1; while(!q.empty()) { u = q.front(); q.pop(); for(i = head[u]; i != -1; i = eg[i].next) { if(eg[i].in == -1) continue; v = eg[i].v; if(!eg[i].hs && eg[i].in)//路未建且在路径中 { printf("%d %d 1\n",u,v); } else if(eg[i].hs && !eg[i].in)//路已建但不在路径中 { printf("%d %d 0\n",u,v); } eg[i].in = eg[i^1].in = -1; if(!vis[v]) { q.push(v); vis[v] = 1; } } } puts("");}int main(){ int u,v,w; scanf("%d %d",&n,&m); memset(head,-1,sizeof(head)); tp = alb = 0; while(m--) { scanf("%d %d %d",&u,&v,&w); Add(u,v,w); Add(v,u,w); if(w) alb++;//累加已建路数 } spfa(); for(u = n; u != pre[u]; u = pre[u]) eg[site[u]].in = eg[site[u]^1].in = 1;//标记最短路径上的路 printf("%d\n",rep[n]*2 + alb - dis[n]);//rep+(alb-(dis-rep)) Bfs(); return 0;}
//spfa+优化93ms #include <iostream>#include <cstdio>#include <cstring>#include <queue>#define sz 100000#define INF 0x3f3f3f3fusing namespace std;typedef struct Edge{ int v,next,hs; int in;}Edge;bool vis[sz+1];Edge eg[2*sz+2];int head[sz+1];int rep[sz+1],dis[sz+1],site[sz+1],pre[sz+1];int alb,n,m,tp;void Add(int u,int v,int w){ eg[tp].v = v; eg[tp].hs = w; eg[tp].next = head[u]; eg[tp].in = 0; head[u] = tp++;}void spfa(){ deque <int> q; memset(vis,0,sizeof(vis)); memset(dis,INF,sizeof(dis)); memset(rep,INF,sizeof(rep)); int i,u,v,p,ned; q.push_front(1); dis[1] = rep[1] = 0; pre[1] = vis[1] = 1; while(!q.empty()) { u = q.front(); q.pop_front(); if(u == n) return; for(i = head[u]; i != -1; i = eg[i].next) { ned = eg[i].hs^1; v = eg[i].v; if(dis[u]+1 < dis[v] || (dis[u]+1 == dis[v] && rep[u] + ned < rep[v])) { site[v] = i; pre[v] = u; dis[v] = dis[u]+1; rep[v] = rep[u] + ned; if(!vis[v]) { if(!q.empty()) p = q.front(); if(!q.empty() && (dis[v] < dis[p] || (dis[v] == dis[p] && rep[v] < rep[p])) )q.push_front(v); else q.push_back(v); vis[v] = 1; } } } }}void Bfs(){ memset(vis,0,sizeof(vis)); queue <int> q; q.push(1); int i,u,v; vis[1] = 1; while(!q.empty()) { u = q.front(); q.pop(); for(i = head[u]; i != -1; i = eg[i].next) { if(eg[i].in == -1) continue; v = eg[i].v; if(!eg[i].hs && eg[i].in) { printf("%d %d 1\n",u,v); } else if(eg[i].hs && !eg[i].in) { printf("%d %d 0\n",u,v); } eg[i].in = eg[i^1].in = -1; if(!vis[v]) { q.push(v); vis[v] = 1; } } } puts("");}int main(){ int u,v,w; scanf("%d %d",&n,&m); memset(head,-1,sizeof(head)); tp = alb = 0; while(m--) { scanf("%d %d %d",&u,&v,&w); Add(u,v,w); Add(v,u,w); if(w) alb++; } spfa(); for(u = n; u != pre[u]; u = pre[u]) eg[site[u]].in = eg[site[u]^1].in = 1; printf("%d\n",rep[n]*2 + alb - dis[n]); Bfs(); return 0;}
//dijkstra+优化108ms#include <iostream>#include <cstdio>#include <cstring>#include <queue>#include <vector>#define sz 100000#define INF 0x3f3f3f3fusing namespace std;typedef struct Edge{ int v,next,hs; int in;}Edge;bool vis[sz+1];Edge eg[2*sz+2];int head[sz+1];int rep[sz+1],dis[sz+1],site[sz+1],pre[sz+1];int alb,n,m,tp;void Add(int u,int v,int w){ eg[tp].v = v; eg[tp].hs = w; eg[tp].next = head[u]; eg[tp].in = 0; head[u] = tp++;}struct cmp{ bool operator() (int a,int b) { return dis[a] > dis[b] || (dis[a] == dis[b] && rep[a] > rep[b]); }};void Dijkstra(){ priority_queue <int,vector<int>,cmp> q; memset(vis,0,sizeof(vis)); memset(dis,INF,sizeof(dis)); memset(rep,INF,sizeof(rep)); dis[1] = rep[1] = 0; pre[1] = 1; q.push(1); int i,v,p,mm,j,ss,ned; while(1) { p = q.top(); q.pop(); if(p == n) return; vis[p] = 1; for(j = head[p]; j != -1; j = eg[j].next) { v = eg[j].v; ned = eg[j].hs^1; if(!vis[v] && (dis[p] + 1 < dis[v] || (dis[p]+1 == dis[v] && rep[p] + ned < rep[v]))) { dis[v] = dis[p] + 1; rep[v] = rep[p] +ned; site[v] = j; pre[v] = p; q.push(v); } } }}void Bfs(){ memset(vis,0,sizeof(vis)); queue <int> q; q.push(1); int i,u,v; vis[1] = 1; while(!q.empty()) { u = q.front(); q.pop(); for(i = head[u]; i != -1; i = eg[i].next) { if(eg[i].in == -1) continue; v = eg[i].v; if(!eg[i].hs && eg[i].in) { printf("%d %d 1\n",u,v); } else if(eg[i].hs && !eg[i].in) { printf("%d %d 0\n",u,v); } eg[i].in = eg[i^1].in = -1; if(!vis[v]) { q.push(v); vis[v] = 1; } } } puts("");}int main(){ int u,v,w; scanf("%d %d",&n,&m); memset(head,-1,sizeof(head)); tp = alb = 0; while(m--) { scanf("%d %d %d",&u,&v,&w); Add(u,v,w); Add(v,u,w); if(w) alb++; } Dijkstra(); for(u = n; u != pre[u]; u = pre[u]) eg[site[u]].in = eg[site[u]^1].in = 1; printf("%d\n",rep[n]*2 + alb - dis[n]); Bfs(); return 0;}
0 0
- 【CF 507E】Breaking Good
- cf 507E Breaking Good 最短路
- Breaking Good - CodeForces 507E
- CodeForces 507E Breaking Good 最短路
- E. Breaking Good
- Codeforces Round #287 (Div. 2) 507E E. Breaking Good
- Codeforces Round #287 (Div. 2) 507 E. Breaking Good
- 507E Breaking Good (最短路+记录路径)
- CodeForces 507E Breaking Good(最短路)
- CodeForces 507E Breaking Good(最短路)
- 最短路Codeforces E. Breaking Good
- Codeforces 509E. Breaking Good SPFA
- Codeforces 507E Breaking Good【最短路SPFA+Dp+记录路径】好题~~~
- Codeforces Round #287 (Div. 2) E. Breaking Good
- codeforces 287DIV2 E - Breaking Good(最短路)
- Codeforces Round #287 (Div. 2) E. Breaking Good 最短路
- cf287 Breaking Good
- CodeForces P507E Breaking Good
- apache自带的ab压力测试工具用法
- Linux下的 .o、.a、.so文件
- Spring MVC入门
- iOS获取当前网页的页面元素
- sublime text使用
- 【CF 507E】Breaking Good
- js 操作cookie
- Python subprocess模块学习总结
- 类的扩展-category和extension
- 详解Oracle多种表连接方式
- 4. JavaScript Math 对象
- mfc单文档获取顶层菜单的菜单项文本,并设置响应菜单命令范围
- asp.net 母版页技术
- RedHat6 系统安装完后的网络配置和YUM镜像源修改