hdu 3191 次短路的长度和个数
http://acm.hdu.edu.cn/showproblem.php?pid=3191
求次短路的长度和个数
相关分析在这里http://blog.csdn.net/u012774187/article/details/40681515
#pragma comment(linker, "/STACK:36777216")
#pragma GCC optimize ("O2")
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <string>
#include <queue>
#include <map>
#include <iostream>
#include <algorithm>
using namespace std;
#define RD(x) scanf("%d",&x)
#define RD2(x,y) scanf("%d%d",&x,&y)
#define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define clr0(x) memset(x,0,sizeof(x))
#define clr1(x) memset(x,-1,sizeof(x))
#define eps 1e-9
const double pi = acos(-1.0);
typedef long long LL;
typedef unsigned long long ULL;
const int modo = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const int inf = 0x3fffffff;
const LL _inf = 1e18;
const int maxn = 55,maxm = 10005;
struct edge{
int v,w,next;
edge(){};
edge(int vv,int ww,int nnext):v(vv),w(ww),next(nnext){};
}e[maxn*maxn*2];
int head[maxn],inq[maxn][2],dist[maxn][2],cnt[maxn][2];//0最短1次短
int n,m,ecnt;
void init()
{
clr1(head);
ecnt = 0;
for(int i = 1;i <= maxn;++i)
dist[i][0] = dist[i][1] = inf;
//fill(dist,dist+maxn*2,inf);
clr0(inq),clr0(cnt);
}
void add(int u,int v,int w)
{
e[ecnt] = edge(v,w,head[u]);
head[u] = ecnt++;
// e[ecnt] = edge(u,w,head[v]);
// head[v] = ecnt++;
}
typedef pair<int,int> p2;
struct cmp {
bool operator() (const p2 &a, const p2 &b)
{
if(dist[a.first][a.second] != dist[b.first][b.second])
return dist[a.first][a.second] > dist[b.first][b.second];
else
return a.first > b.first;
}
};
void spfa(int src,int dst)
{
priority_queue<p2 , vector<p2> , cmp> q;
q.push(make_pair(src,0));
dist[src][0] = 0,cnt[src][0] = 1;
while(!q.empty()){
int u = q.top().first,flag = q.top().second;
q.pop();
if(inq[u][flag]) continue;
inq[u][flag] = 1;
for(int i = head[u];i != -1;i = e[i].next){
int v = e[i].v,w = e[i].w;
if(!inq[v][0] && dist[v][0] > dist[u][flag] + e[i].w){
if(dist[v][0] != inf){
dist[v][1] = dist[v][0];
cnt[v][1] = cnt[v][0];
q.push(make_pair(v,1));
}
dist[v][0] = dist[u][flag] + e[i].w;
cnt[v][0] = cnt[u][flag]; q.push(make_pair(v,0));
}else if(!inq[v][0] && dist[v][0] == dist[u][flag] + e[i].w){
cnt[v][0] += cnt[u][flag];
}else if(!inq[v][1] && dist[v][1] > dist[u][flag] + e[i].w){
dist[v][1] = dist[u][flag] + e[i].w;
cnt[v][1] = cnt[u][flag]; q.push(make_pair(v,1));
}else if(!inq[v][1] && dist[v][1] == dist[u][flag] + e[i].w){
cnt[v][1] += cnt[u][flag];
}
}
}
printf("%d %d\n",dist[dst][1],cnt[dst][1]);
} int main(){
int u,v,w,s,t;
while(~RD2(n,m)){
RD2(s,t);s++,t++;
init();
while(m--){
RD3(u,v,w);u++,v++;
add(u,v,w);
}
spfa(s,t);
}
return 0;
}
上面是错误代码
经过筛查,发现是
if(dist[a.first][a.second] != dist[b.first][b.second])
return dist[a.first][a.second] > dist[b.first][b.second];
有问题,因为不同的路径到达同一个点的同一个状态的值不一样,所有比较和更新穿插在一起就会出错了
可是每次更新dist数组都是向小了更新,所以不应该有影响啊..?
以下是AC代码,谁能清楚一点地告诉为啥上面的程序就不对呢?
#pragma comment(linker, "/STACK:36777216")
#pragma GCC optimize ("O2")
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <string>
#include <queue>
#include <map>
#include <iostream>
#include <algorithm>
using namespace std;
#define RD(x) scanf("%d",&x)
#define RD2(x,y) scanf("%d%d",&x,&y)
#define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define clr0(x) memset(x,0,sizeof(x))
#define clr1(x) memset(x,-1,sizeof(x))
#define eps 1e-9
const double pi = acos(-1.0);
typedef long long LL;
typedef unsigned long long ULL;
const int modo = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const int inf = 0x3fffffff;
const LL _inf = 1e18;
const int maxn = 55,maxm = 10005;
struct edge{
int v,w,next;
edge(){};
edge(int vv,int ww,int nnext):v(vv),w(ww),next(nnext){};
}e[maxn*maxn*2];
int head[maxn],inq[maxn][2],dist[maxn][2],cnt[maxn][2];//0最短1次短
int n,m,ecnt;
struct node{
int v,flag,dis;
node(int a,int b,int c):v(a),flag(b),dis(c){};
bool operator < (const node & a) const{
if(a.dis == dis)
return a.v < v;
return a.dis < dis;
}
};
void init()
{
clr1(head);
ecnt = 0;
for(int i = 0;i <= n;++i)
dist[i][0] = dist[i][1] = inf;
//fill(dist,dist+maxn*2,inf);
clr0(inq),clr0(cnt);
}
void add(int u,int v,int w)
{
e[ecnt] = edge(v,w,head[u]);
head[u] = ecnt++;
// e[ecnt] = edge(u,w,head[v]);
// head[v] = ecnt++;
}
void spfa(int src,int dst)
{
priority_queue<node> q;
q.push(node(src,0,0));
dist[src][0] = 0,cnt[src][0] = 1;
while(!q.empty()){
int u = q.top().v,flag = q.top().flag,dis = q.top().dis;
q.pop();
if(inq[u][flag]) continue;
inq[u][flag] = 1;
for(int i = head[u];i != -1;i = e[i].next){
int v = e[i].v,w = e[i].w;
if(!inq[v][0] && dist[v][0] > dis + e[i].w){
if(dist[v][0] != inf){
dist[v][1] = dist[v][0];
cnt[v][1] = cnt[v][0];
q.push(node(v,1,dist[v][1]));
}
dist[v][0] = dis + e[i].w;
cnt[v][0] = cnt[u][flag]; q.push(node(v,0,dist[v][0]));
}else if(!inq[v][0] && dist[v][0] == dis + e[i].w){
cnt[v][0] += cnt[u][flag];
}else if(!inq[v][1] && dist[v][1] > dis + e[i].w){
dist[v][1] = dis + e[i].w;
cnt[v][1] = cnt[u][flag]; q.push(node(v,1,dist[v][1]));
}else if(!inq[v][1] && dist[v][1] == dis+ e[i].w){
cnt[v][1] += cnt[u][flag];
}
}
}
printf("%d %d\n",dist[dst][1],cnt[dst][1]);
} int main(){
int u,v,w,s,t;
while(~RD2(n,m)){
RD2(s,t);s++,t++;
init();
while(m--){
RD3(u,v,w);u++,v++;
add(u,v,w);
}
spfa(s,t);
}
return 0;
}
AC代码2
#pragma comment(linker, "/STACK:36777216")
#pragma GCC optimize ("O2")
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <string>
#include <queue>
#include <map>
#include <iostream>
#include <algorithm>
using namespace std;
#define RD(x) scanf("%d",&x)
#define RD2(x,y) scanf("%d%d",&x,&y)
#define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define clr0(x) memset(x,0,sizeof(x))
#define clr1(x) memset(x,-1,sizeof(x))
#define eps 1e-9
const double pi = acos(-1.0);
typedef long long LL;
typedef unsigned long long ULL;
const int modo = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const int inf = 0x3fffffff;
const LL _inf = 1e18;
const int maxn = 55,maxm = 10005;
struct edge{
int v,w,next;
edge(){};
edge(int vv,int ww,int nnext):v(vv),w(ww),next(nnext){};
}e[maxn*maxn*2];
int head[maxn],inq[maxn][2],dist[maxn][2],cnt[maxn][2];//0最短1次短
int n,m,ecnt;
struct node{
int v,flag,dis;
node(int a,int b,int c):v(a),flag(b),dis(c){};
bool operator < (const node & a) const{
if(a.dis == dis)
return a.v < v;
return a.dis < dis;
}
};
void init()
{
clr1(head);
ecnt = 0;
for(int i = 0;i <= n;++i)
dist[i][0] = dist[i][1] = inf;
//fill(dist,dist+maxn*2,inf);
clr0(inq),clr0(cnt);
}
void add(int u,int v,int w)
{
e[ecnt] = edge(v,w,head[u]);
head[u] = ecnt++;
// e[ecnt] = edge(u,w,head[v]);
// head[v] = ecnt++;
}
void spfa(int src,int dst)
{
priority_queue<node> q;
q.push(node(src,0,0));
dist[src][0] = 0,cnt[src][0] = 1;
while(!q.empty()){
int u = q.top().v,flag = q.top().flag;//dis = q.top().dis;
q.pop();
if(inq[u][flag]) continue;
inq[u][flag] = 1;
for(int i = head[u];i != -1;i = e[i].next){
int v = e[i].v,w = e[i].w;
if(!inq[v][0] && dist[v][0] > dist[u][flag] + e[i].w){
if(dist[v][0] != inf){
dist[v][1] = dist[v][0];
cnt[v][1] = cnt[v][0];
q.push(node(v,1,dist[v][1]));
}
dist[v][0] = dist[u][flag] + e[i].w;
cnt[v][0] = cnt[u][flag]; q.push(node(v,0,dist[v][0]));
}else if(!inq[v][0] && dist[v][0] == dist[u][flag] + e[i].w){
cnt[v][0] += cnt[u][flag];
}else if(!inq[v][1] && dist[v][1] > dist[u][flag] + e[i].w){
dist[v][1] = dist[u][flag] + e[i].w;
cnt[v][1] = cnt[u][flag]; q.push(node(v,1,dist[v][1]));
}else if(!inq[v][1] && dist[v][1] == dist[u][flag] + e[i].w){
cnt[v][1] += cnt[u][flag];
}
}
}
printf("%d %d\n",dist[dst][1],cnt[dst][1]);
} int main(){
int u,v,w,s,t;
while(~RD2(n,m)){
RD2(s,t);s++,t++;
init();
while(m--){
RD3(u,v,w);u++,v++;
add(u,v,w);
}
spfa(s,t);
}
return 0;
}
<queue>#include <map>#include <iostream>#include <algorithm>using namespace std;#define RD(x) scanf("%d",&x)#define RD2(x,y) scanf("%d%d",&x,&y)#define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)#define clr0(x) memset(x,0,sizeof(x))#define clr1(x) memset(x,-1,sizeof(x))#define
eps 1e-9const double pi = acos(-1.0);typedef long long LL;typedef unsigned long long ULL;const int modo = 1e9 + 7;const int INF = 0x3f3f3f3f;const int inf = 0x3fffffff;const LL _inf = 1e18;const int maxn = 55,maxm = 10005;struct edge{ int v,w,next; edge(){};
edge(int vv,int ww,int nnext):v(vv),w(ww),next(nnext){};}e[maxn*maxn*2];int head[maxn],inq[maxn][2],dist[maxn][2],cnt[maxn][2];//0最短1次短int n,m,ecnt;void init(){ clr1(head); ecnt = 0; for(int i = 0;i < maxn;++i) dist[i][0] = dist[i][1] = inf; //fill(dist,dist+maxn*2,inf);
clr0(inq),clr0(cnt);}void add(int u,int v,int w){ e[ecnt] = edge(v,w,head[u]); head[u] = ecnt++;// e[ecnt] = edge(u,w,head[v]);// head[v] = ecnt++;}typedef pair<int,int> p2;struct cmp { bool operator() (const p2 &a, const p2 &b) { if(dist[a.first][a.second]
!= dist[b.first][b.second]) return dist[a.first][a.second] > dist[b.first][b.second]; else return a.first > b.first; }};void spfa(int src,int dst){ priority_queue<p2 , vector<p2> , cmp> q; q.push(make_pair(src,0)); dist[src][0] = 0,cnt[src][0] = 1; while(!q.empty()){
int u = q.top().first,flag = q.top().second; q.pop(); if(inq[u][flag]) continue; inq[u][flag] = 1; for(int i = head[u];i != -1;i = e[i].next){ int v = e[i].v,w = e[i].w; if(!inq[v][0] && dist[v][0] > dist[u][flag] + e[i].w){ if(dist[v][0] != inf){ dist[v][1]
= dist[v][0]; cnt[v][1] = cnt[v][0]; q.push(make_pair(v,1)); } dist[v][0] = dist[u][flag] + e[i].w; cnt[v][0] = cnt[u][flag]; q.push(make_pair(v,0)); }else if(!inq[v][0] && dist[v][0] == dist[u][flag] + e[i].w){ cnt[v][0] += cnt[u][flag]; }else if(!inq[v][1]
&& dist[v][1] > dist[u][flag] + e[i].w){ dist[v][1] = dist[u][flag] + e[i].w; cnt[v][1] = cnt[u][flag]; q.push(make_pair(v,1)); }else if(!inq[v][1] && dist[v][1] == dist[u][flag] + e[i].w){ cnt[v][1] += cnt[u][flag]; } } } printf("%d %d\n",dist[dst][1],cnt[dst][1]);}int
main(){ int u,v,w,s,t; while(~RD2(n,m)){ RD2(s,t);s++,t++; init(); while(m--){ RD3(u,v,w);u++,v++; add(u,v,w); } spfa(s,t); } return 0;}
hdu 3191 次短路的长度和个数的更多相关文章
- HDU 3191 次短路长度和条数
		
http://www.cnblogs.com/wally/archive/2013/04/16/3024490.html http://blog.csdn.net/me4546/article/det ...
 - HDU3191-How many paths are there(次短路的长度及其个数)
		
oooccc1 is a Software Engineer who has to ride to the work place every Monday through Friday. For a ...
 - COJ 0579 4020求次短路的长度
		
4020求次短路的长度 难度级别:C: 运行时间限制:1000ms: 运行空间限制:51200KB: 代码长度限制:2000000B 试题描述 在一个地图上共有N个路口(编号分别为1到N),R条道路( ...
 - HDU - 2066 最短路+加一个节点
		
一个图上,有M条边,Z个出发点,Y个终止点.求一条最短路,其中起点是Z中的任意一点,终点是Y中任意一点. Input 输入数据有多组,输入直到文件结束. 每组的第一行是三个整数M,Z,Y 接着有M行, ...
 - ACM:   HDU 2544 最短路-Dijkstra算法
		
HDU 2544最短路 Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Descrip ...
 - 【最长下降子序列的长度和个数】 poj 1952
		
转自http://blog.csdn.net/zhang360896270/article/details/6701589 这题要求最长下降子序列的长度和个数,我们可以增加数组maxlen[size] ...
 - UESTC 30 &&HDU 2544最短路【Floyd求解裸题】
		
最短路 Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submiss ...
 - hdu 5521 最短路
		
Meeting Time Limit: 12000/6000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)Total ...
 - HDU 5726 GCD 区间GCD=k的个数
		
GCD Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submis ...
 
随机推荐
- 1C - A + B Problem II
			
I have a very simple problem for you. Given two integers A and B, your job is to calculate the Sum o ...
 - PAT 1002 写出这个数 (20)(代码)
			
1002 写出这个数 (20)(20 分) 读入一个自然数n,计算其各位数字之和,用汉语拼音写出和的每一位数字. 输入格式:每个测试输入包含1个测试用例,即给出自然数n的值.这里保证n小于10^100 ...
 - 线性表(java)
			
线性表 概念:零个或者多个数据元素的有限序列. 特点:除了第一个元素没有前驱结点,最后一个元素没有后继结点外,其它元素有且仅有一个直接前驱和一个直接后继结点.元素的个数必定为有限个. 实现: 定义一个 ...
 - Real-time qPCR So Easy?
			
Real-time qPCR So Easy? [2016-05-27] 实时荧光定量PCR技术是在定性RCR技术基础上发展起来的核酸定量技术,于1996年由美国Applied biosy ...
 - UI设计教程分享:关于海报的合成过程
			
一张好的产品创意合成海报,能瞬间提升商品价值感,同时场景和相关元素的融入,让消费者瞬间明白商品属性及内涵.同时为商品营造的使用场景拥有更强的代入感,从而刺激转化.好的创意合成海报能为消费者带来视觉冲击 ...
 - mfc获取exe的版本信息
			
CString GetFileVersion(const CString& sTargetFileName){ DWORD nInfoSize = 0, dwHandle = 0; nInfo ...
 - Python之路番外(第三篇):Pycharm的使用秘籍
			
版本:Pycharm2017.3.4Professional Edition 一.Pycharm的基本使用1.在Pycharm下为你的python项目配置python解释器 file --settin ...
 - Python之路(第五篇) Python基本数据类型集合、格式化、函数
			
一.变量总结 1.1 变量定义 记录某种状态或者数值,并用某个名称代表这个数值或状态. 1.2 变量在内存中的表现形式 Python 中一切皆为对象,数字是对象,列表是对象,函数也是对象,任何东西都是 ...
 - [Python]Python章1 Python中_的故事
			
_xx 单下划线开头 Python中没有真正的私有属性或方法,可以在你想声明为私有的方法和属性前加上单下划线,以提示该属性和方法不应在外部调用.如果真的调用了也不会出错,但不符合规范. 本文为译文,版 ...
 - PreparedStatement批量处理和事务
			
PreparedStatement批量处理和事务代码如下: /* * PreparedStatement: 1.addBatch() 将一组参数添加到 PreparedStatement对象内部 2. ...