POJ 3463
题意:求最短路和比最短路长1个单位的路的数量之和。
用dijkstra求出最短路和次短路数量,判断次短路是否比最短路长1单位输出和。
#include<cstdio>
#include<cstring>
#include<queue>
#define MAXE 10001
#define MAXV 1001
using namespace std;
const long long INF=(long long)1<<63-1;
typedef pair<long long,long long> pii;
long long t,m,n,V,E,pos=0,head[MAXV];
long long ans,d[2][MAXV],num[2][MAXV];
//bool can1[MAXV][MAXV],can2[MAXV][MAXE*2];
bool cannot=0;
struct Edge
{
long long w,next,u,v;
}node[MAXE*2];
//无向图邻接表
struct dian
{
long long id,d,c;
bool operator <(const dian &a) const
{
return d>a.d;
}
};
void add(long long u,long long v,long long w)
{
if(u==v) return;
node[pos].u=u; //如果指向自己的边则舍去
node[pos].v=v;
node[pos].w=w;
node[pos].next=head[u];
head[u]=pos++;
}
//S为起点标号
void dijkstra(long long s)
{
for(long long i=0;i<=V;i++) d[0][i]=d[1][i]=INF;
d[0][s]=0;
num[0][s]=1;
priority_queue<dian> q;
bool done[2][MAXV];
memset(done,0,sizeof(done));
dian now;
now.d=d[0][s];now.c=0;now.id=s;
q.push(now);
while(!q.empty()){
dian u=q.top();q.pop();
long long x=u.id,c=u.c;
if(c==1 && x==4)
int ting=100;
if(done[c][x]) continue;
done[c][x]=true;
for(long long i=head[x];i!=-1;i=node[i].next){ //亮点在松弛
if(!done[0][node[i].v] && d[0][node[i].v]>u.d+node[i].w){ //发现更优解,把当前最短路赋给次短路,再更新最短路,均入队列
d[1][node[i].v]=d[0][node[i].v];
num[1][node[i].v]=num[0][node[i].v];
num[0][node[i].v]=num[c][x];
d[0][node[i].v]=u.d+node[i].w;
dian temp;
temp.c=0;temp.d=d[0][node[i].v];temp.id=node[i].v;
q.push(temp);
temp.c=1;temp.d=d[1][node[i].v];temp.id=node[i].v;
q.push(temp);
}
else if(d[0][node[i].v]==u.d+node[i].w) //更新最短路数量
num[0][node[i].v]+=num[c][x];
else if(d[1][node[i].v]>u.d+node[i].w){ //更新次短路
d[1][node[i].v]=u.d+node[i].w;
num[1][node[i].v]=num[c][x];
dian temp;
temp.c=1;temp.d=d[1][node[i].v];temp.id=node[i].v;
q.push(temp);
}
else if(d[1][node[i].v]==u.d+node[i].w) //更新次短路数量
num[1][node[i].v]+=num[c][x];
}
}
}
int main()
{
//freopen("in","r",stdin);
//freopen("out","w",stdout);
long long u,v,w,s,t,n;
scanf("%lld",&n);
for(long long l=0;l<n;l++){
scanf("%lld%lld",&V,&E);
pos=1;ans=0;
memset(head,-1,sizeof(head));
memset(num,0,sizeof(num));
for(long long i=0;i<E;i++){
scanf("%lld%lld%lld",&u,&v,&w);
add(u,v,w);
}
scanf("%lld%lld",&s,&t);
dijkstra(s);
ans=num[0][t];
if(d[1][t]==d[0][t]+1)
ans+=num[1][t];
printf("%lld\n",ans);
}
return 0;
}
不会求k短路然后一直以为直接求比最短路长1的路,各种错,唉~待会儿把次短路看一下吧= =
顺便吐槽一下西安的天气,在看了boat题解后豁然开朗…然后还是改了一个下午,小爷被热的各种脑残,ORZ……