题意:求出一个图的最短路的数量,并求出在最短路的条件下求出获得权值最大的路。
我的做法就是用优先队列优化Dijkstra算法,就是在mindis[v]>mindis[number]+dis[i](i是边的编号,v是边的终点,number是边的始点),或者在mindis[v]==mindis[number]+dis[i]的条件下maxcost[v]<num[v]+maxcost[number]就需要松弛。
但是由于对优先队列的使用不是非常熟悉,于是自己坑了自己,在重载<运算符的时候,搞错了,于是WA了一天。
#include<iostream> #include<vector> #include<algorithm> #include<cstdio> #include<queue> #include<stack> #include<string> #include<map> #include<set> #include<cmath> #include<cassert> #include<cstring> #include<iomanip> #include<ctime> #include<climits> using namespace std; int pre[505]; int num[505]; int vv[26000],fir[505],nxt[26000],dis[26000]; int maxcost[505],mindis[505]; bool vis[505]; int e; struct Pnt { int mindis,num; Pnt(int mindis,int num) { this->mindis=mindis; this->num=num; } Pnt(){} bool operator <(const Pnt& b)const { return mindis>b.mindis; } }; void add(int u,int v,int cost) { dis[e]=cost; vv[e]=v; nxt[e]=fir[u]; fir[u]=e++; } priority_queue<Pnt>que; vector<int>vec; int dfs(int sta,int end,int len) { vis[sta]=1; int res=0; if(sta==end&&!len) res=1; else if(len<0) res=0; else { for(int i=fir[sta];i!=-1;i=nxt[i]) { if(!vis[vv[i]]) res+=dfs(vv[i],end,len-dis[i]); } } vis[sta]=0; return res; } int main() { int n,m,r1,r2; while(scanf("%d%d%d%d",&n,&m,&r1,&r2)!=EOF) { vec.clear(); e=0; memset(pre,-1,sizeof(pre)); memset(fir,-1,sizeof(fir)); memset(vis,0,sizeof(vis)); memset(maxcost,-1,sizeof(maxcost)); for(int i=0;i<n;i++) { scanf("%d",&num[i]); mindis[i]=INT_MAX; } int u,v,cost; for(int i=0;i<m;i++) { scanf("%d%d%d",&u,&v,&cost); add(u,v,cost); add(v,u,cost); } while(!que.empty()) que.pop(); maxcost[r1]=num[r1]; mindis[r1]=0; que.push(Pnt(0,r1)); while(!que.empty()) { Pnt top=que.top(); que.pop(); int number=top.num; //cout<<"number="<<number<<endl; if(vis[number]) continue; vis[number]=1; for(int i=fir[number];i!=-1;i=nxt[i]) { int v=vv[i]; //cout<<"v="<<v<<" (number="<<number<<")"<<endl; if(mindis[v]>mindis[number]+dis[i]) { mindis[v]=mindis[number]+dis[i]; pre[v]=number; maxcost[v]=maxcost[number]+num[v]; que.push(Pnt(mindis[v],v)); } else if(mindis[v]==mindis[number]+dis[i]&&maxcost[v]<num[v]+maxcost[number]) { pre[v]=number; maxcost[v]=maxcost[number]+num[v]; que.push(Pnt(mindis[v],v)); } } } memset(vis,0,sizeof(vis)); //count the number printf("%d %d\n",dfs(r1,r2,mindis[r2]),maxcost[r2]); //get the route int tem=r2; while(tem!=r1) { //cout<<"bad\n"; vec.push_back(tem); tem=pre[tem]; } vec.push_back(r1); int size=vec.size(); printf("%d",vec[size-1]); for(int i=size-2;i>=0;i--) { printf(" %d",vec[i]); } printf("\n"); } return 0; }