POJ 3463 Sightseeing (最短路&次短路条数问题)

来源:互联网 发布:大数据培训骗局 编辑:程序博客网 时间:2024/06/05 17:50

题意:给一个有向图,求从s到f 的最短路+最短路-1的条数。   有重边。


分析: 代码是根据挑战的次短路改编的。      具体请看代码。



#include<iostream>#include<algorithm>#include<cstdio>#include<cmath>#include<cstring>#include<string>#include<vector>#include<cctype>#include<set>#include<map>#include<queue>#include<stack>#include<iomanip>#include<sstream>#include<limits>#define ll long long#define inf 0x3f3f3f3fusing namespace std;const ll INF = 1e18;const int maxn = 2e5+10;const ll MOD = 1000000007;const double EPS = 1e-10;const double Pi = acos(-1.0);struct edge{int to,cost;};//typedef pair<int,int>P; //1 dist 2 ustruct P{    int first,second,z;   //z 标志是最短路还是次短路    P(int a=0,int b=0,int c=0):first(a),second(b),z(c){}    bool operator < (const P &rhs)const{return first>rhs.first;}};int V;vector<edge>G[maxn];int d[maxn],d2[maxn],cnt1[maxn],cnt2[maxn],vis[maxn][2];  //d cnt1 最短路长度及数量 d2 cnt2 次短路长度及数量  vis代表有没访问过void dij(int s){    priority_queue<P >que;    fill(d,d+V+1,inf);    fill(d2,d2+V+1,inf);    d[s] = 0;    cnt1[s] = 1;    que.push(P(0,s,0));    while(!que.empty())    {        P p = que.top(); que.pop();        int v = p.second, z = p.z;        if (d2[v] < p.first || vis[v][z]) continue;        vis[v][z] = 1;       //一定要记录是否访问过,不然会出错,因为是单调队列。        for(int i = 0; i < G[v].size();i++)        {            edge e = G[v][i];            int temp = p.first + e.cost;            if (d[e.to] > temp)  // 比最短路短            {                d2[e.to] = d[e.to];                d[e.to] = temp;                cnt2[e.to] = cnt1[e.to];                cnt1[e.to] = z==0? cnt1[v]:cnt2[v];   //要弄清楚等于哪个。                que.push(P(d[e.to] ,e.to,0));                que.push(P(d2[e.to] ,e.to,1));            }else              if (d[e.to] == temp) cnt1[e.to] += z==0? cnt1[v]:cnt2[v];   // 等于最短路              else                if (temp < d2[e.to])   // 比次短路短                {                    d2[e.to] = temp;                    cnt2[e.to] = z==0? cnt1[v]:cnt2[v];                    que.push(P(d2[e.to] ,e.to,1));                }else if (temp == d2[e.to]) cnt2[e.to] += z==0? cnt1[v]:cnt2[v];  // 等于次短路        }    }}int main(){#ifdef LOCALfreopen("C:\\Users\\lanjiaming\\Desktop\\acm\\in.txt","r",stdin);//freopen("output.txt","w",stdout);#endif//ios_base::sync_with_stdio(0);     int T,n,m;     scanf("%d",&T);     while(T--)     {         scanf("%d%d",&n,&m);         for(int  i = 0; i <= n; i++) G[i].clear();         V = n;         for(int i = 0; i < m; i++)         {             int a,b,l;             scanf("%d%d%d",&a,&b,&l);             G[a].push_back(edge{b,l});         }         int s,f;         scanf("%d%d",&s,&f);         memset(cnt1,0,sizeof cnt1);         memset(cnt2,0,sizeof cnt2);         memset(vis,0,sizeof vis);         dij(s);         if (d[f] == d2[f]-1) cnt1[f] += cnt2[f];         printf("%d\n",cnt1[f]);     }    return 0;}


0 0
原创粉丝点击