HDU 1688 Sightseeing 【次短路条数】
2015-11-11 19:39
543 查看
题意:就是求最短路条数和特殊次短路(比最短路长1)的和。
思路:
四种更新策略:
1:新的路比最短路小,更新最短路和次短路;
2:新的路和最短路相等,计数;
3:新的路比最短路长但是比刚刚的次短路短,更新次短路;
4:新的路和次短路相等,计数;
蒽,然后就是Dijsktra+堆优化跑一下就好了;
思路:
四种更新策略:
1:新的路比最短路小,更新最短路和次短路;
2:新的路和最短路相等,计数;
3:新的路比最短路长但是比刚刚的次短路短,更新次短路;
4:新的路和次短路相等,计数;
蒽,然后就是Dijsktra+堆优化跑一下就好了;
#include<stdio.h> #include<string.h> #include<algorithm> #include<stdio.h> #include<string.h> #include<algorithm> #include<math.h> #include<iostream> #include<stdlib.h> #include<set> #include<map> #include<queue> #include<stack> #include<vector> #include<bitset> #pragma comment(linker, "/STACK:1024000000,1024000000") template <class T> bool scanff(T &ret){ char c; int sgn; T bit=0.1; if(c=getchar(),c==EOF) return 0; while(c!='-'&&c!='.'&&(c<'0'||c>'9')) c=getchar(); sgn=(c=='-')?-1:1; ret=(c=='-')?0:(c-'0'); while(c=getchar(),c>='0'&&c<='9') ret=ret*10+(c-'0'); if(c==' '||c=='\n'){ ret*=sgn; return 1; } while(c=getchar(),c>='0'&&c<='9') ret+=(c-'0')*bit,bit/=10; ret*=sgn; return 1; } #define inf 1073741824 #define llinf 4611686018285162540LL #define eps 1e-8 #define mod 9223372034707292160LL #define pi acos(-1.0) #define lth (th<<1) #define rth (th<<1|1) #define rep(i,a,b) for(int i=a;i<=b;i++) #define drep(i,a,b) for(int i=a;i>=b;i--) #define mset(x,val) memset(x,val,sizeof(x)) #define mcpy(x,y) memcpy(x,y,sizeof(y)) #define findx(x) lower_bound(b+1,b+1+bn,x)-b #define mpii(a,b) make_pair(a,b); #define NN 101010 #define MM 202020 using namespace std; typedef long long ll; typedef long double lb; typedef pair<int,int> pii; int n,m,casn,s,e; struct Edge{ int to,val,nx; Edge(){} Edge(int t,int v,int n){ to=t,val=v,nx=n; } }ed[MM]; struct node{ int pos,dis; int type; node(){} node(int p,int v,int m){ pos=p,dis=v,type=m; } bool operator < (const node& a)const{ return dis>a.dis; } }; int start[1111],lm; void init(){ lm=0; mset(start,-1); } void add(int x,int y,int v){ ed[lm]=Edge(y,v,start[x]); start[x]=lm++; } int cnt[1111][3],dis[1111][3],vis[1111][3]; void Dijkstra(){ rep(i,1,n){ dis[i][1]=dis[i][2]=inf; vis[i][1]=vis[i][2]=0; cnt[i][1]=cnt[i][2]=0; } dis[s][1]=0; cnt[s][1]=1; vis[s][1]=1; priority_queue<node> q; q.push(node(s,0,1)); int x=s,t=1,d=0; while(true){ for(int i=start[x];~i;i=ed[i].nx){ Edge& e=ed[i]; if(d+e.val<dis[e.to][1]){ if(dis[e.to][1]!=inf){ dis[e.to][2]=dis[e.to][1]; cnt[e.to][2]=cnt[e.to][1]; q.push(node(e.to,dis[e.to][2],2)); } dis[e.to][1]=d+e.val; cnt[e.to][1]=cnt[x][t]; q.push(node(e.to,dis[e.to][1],1)); } else if(d+e.val==dis[e.to][1]){ cnt[e.to][1]+=cnt[x][t]; } else if(d+e.val<dis[e.to][2]){ dis[e.to][2]=d+e.val; cnt[e.to][2]=cnt[x][t]; q.push(node(e.to,dis[e.to][2],2)); } else if(d+e.val==dis[e.to][2]){ cnt[e.to][2]+=cnt[x][t]; } } while(!q.empty()&&vis[q.top().pos][q.top().type]==1) q.pop(); if(q.empty()) break; vis[x=q.top().pos][t=q.top().type]=1; d=q.top().dis; q.pop(); } } int main(){ scanf("%d",&casn); rep(cas,1,casn){ scanf("%d%d",&n,&m); init(); rep(i,1,m){ int u,v,w; scanf("%d%d%d",&u,&v,&w); add(u,v,w); } scanf("%d%d",&s,&e); Dijkstra(); int ans=cnt[e][1]; if(dis[e][1]+1==dis[e][2]){ ans=cnt[e][1]+cnt[e][2]; } printf("%d\n",ans); } return 0; }
相关文章推荐
- 数据结构学习 链表的建立
- 基于opencv的相机之图片处理首页效果(六)
- 转:ios review推送与执行
- SQL语句执行效率及分析(note)
- 快速排序中的分割算法实现
- nyoj--86--找球号(一)(hash&&set&&二分)
- Debian系统apt-get命令整理修改更新源
- 树莓派从零安装物联网alljoyn环境
- nyoj--86--找球号(一)(hash&&set&&二分)
- 扯扯DNS解析的流程
- tomcat内存不足,一段时间后不响应了
- nyoj 找球号(三) 528 (位运算&&set)
- Notification--通知
- stringBuffer 与StringBulider长度分析
- 基于opencv的相机之增加图库功能(五)
- 字符串NSString和不可变字符串NSMutableString的基础知识
- Codeforces 2A. Winner
- 超级终端连接开发板出现Please press Enter to activate this console的问题
- KVM虚拟化基本管理
- P54 5.北京某高校可用的电话号码有以下几类:校内电话号码由4位数字组成,第一位数字不是0,;校外电话又分为本市电话和外地电话两类,拨校外电话需先拨0,若是本市电话则再接拨8位数字(第一位不是0),若是外地电话则拨3位区码再拨8位电话号码(第一位不是0)