HDU 1688 Sightseeing

题目链接:Sightseeing

题意:求最短路和比最短路长度+1的所有路径条数。

附代码:用数组记录最短和次短路径的长度和条数,一次更新,直到没有边可以更新。

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <vector>
using namespace std;
#define maxn 1010

struct Node {
    int to, val;
    Node(int to, int val) {
        this->to = to;
        this->val = val;
    }
};// 保存每个点的所有边及其权值

vector<Node> edge[maxn];

int step[maxn][2]; //bushu[i][j] 表示i点第j短路的长度
int cnt[maxn][2]; // cnt[i][j]表示i点第j短路的条数

int main() {
    int t;
    scanf("%d", &t);
    while(t--) {
        int n, m;
        scanf("%d%d", &n, &m);

        for (int i=1; i<=n; ++i) {
            edge[i].clear();
            step[i][0] = maxn*maxn;
            step[i][1] = maxn*maxn;
            cnt[i][0] = 0;
            cnt[i][1] = 0;
        }

        for (int i=0; i<m; ++i) {
            int x, y, z;
            scanf("%d%d%d", &x, &y, &z);
            edge[x].push_back(Node(y, z));
        }

        int st, ed;
        scanf("%d%d", &st, &ed);

        step[st][0] = 0; // 初始化源点
        step[st][1] = maxn*maxn;
        cnt[st][0] = 1;
        cnt[st][1] = 0;

        bool ok = false;

        while(1) {
           ok = false;
            for (int i=1; i<=n; ++i) {
               for (int k=0; k<2; ++k) {
                   if (cnt[i][k] && i != ed) {
                   for (int j=0; j<edge[i].size(); ++j) {
                        int to = edge[i][j].to;
                        int val = edge[i][j].val;

                            if (step[to][0] > step[i][k] + val) { // 更新最短路
                                step[to][1] = step[to][0];
                                cnt[to][1] = cnt[to][0];
                                step[to][0] = step[i][k] + val;
                                cnt[to][0] = cnt[i][k];
                                ok = true;
                            }
                            else if (step[to][0] == step[i][k] + val) {
                                cnt[to][0] += cnt[i][k];
                                ok = true;
                            }
                            else if (step[to][1] > step[i][k] + val) { // 更新次短路
                                step[to][1] = step[i][k] + val;
                                cnt[to][1] = cnt[i][k];
                                ok = true;
                            }
                            else if (step[to][1] == step[i][k] + val) {
                                cnt[to][1] += cnt[i][k];
                                ok = true;
                            }
                        }
                     cnt[i][k] = 0;
                   }
               }
            }
            if (ok == false) break;
        }

//        for (int i=1; i<=n; ++i) {
//            cout << i << "==" << step[i][0] << " " << cnt[i][0] << " " << step[i][1] << " " << cnt[i][1] << endl;
//        }
        int ans = cnt[ed][0];
        if (step[ed][1] == step[ed][0] + 1) {
            ans += cnt[ed][1];
        }
        printf("%d\n", ans);
    }
    return 0;
}
/*
HDU 1688
*/

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <vector>
#define maxn 1010
#include <queue>
using namespace std;

struct Node {
    int v, w;
    Node(int v, int w) {
        this->v = v;
        this->w = w;
    }
};

vector <Node> edge[maxn];
int st, ed;
int step[maxn][2];
int cnt[maxn][2];
int mp[maxn][maxn];

void bfs(int st) {
    queue<int> que;
    que.push(st);
    while(!que.empty()) {
        int now = que.front();
        que.pop();
       // cout << now << "-----------------\n";
        for (int k=0; k<2; ++k) {
            if (cnt[now][k] && now != ed) {
                for (int j=0; j<edge[now].size(); ++j) {
                    int v = edge[now][j].v;
                    int val = edge[now][j].w;
                    if (step[v][0] > step[now][k] + val) {
                        step[v][1] = step[v][0];
                        cnt[v][1] = cnt[v][0];
                        step[v][0] = step[now][k] + val;
                        cnt[v][0] = cnt[now][k];
                        que.push(v);
                       // cout << v << "==1==" << step[v][0] << " " << cnt[v][0] << " " << step[v][1] << " " << cnt[v][1] << endl;
                    }
                    else if (step[v][0] == step[now][k] + val) {
                        cnt[v][0] += cnt[now][k];
                        que.push(v);
                       // cout << v << "==2==" << step[v][0] << " " << cnt[v][0] << " " << step[v][1] << " " << cnt[v][1] << endl;
                    }
                    else if (step[v][1] > step[now][k] + val) {
                        step[v][1] = step[now][k] + val;
                        cnt[v][1] = cnt[now][k];
                        que.push(v);
                       // cout << v << "==3==" << step[v][0] << " " << cnt[v][0] << " " << step[v][1] << " " << cnt[v][1] << endl;
                    }
                    else if (step[v][1] == step[now][k] + val) {
                        cnt[v][1] += cnt[now][k];
                        que.push(v);
                        //cout << v << "==4==" << step[v][0] << " " << cnt[v][0] << " " << step[v][1] << " " << cnt[v][1] << endl;
                    }
                }
                cnt[now][k] = 0;
            }
        }
    }
}

int main() {
    int t;
    scanf("%d", &t);
    while(t--) {
        int n, m;
        scanf("%d%d", &n, &m);
        for (int i=1; i<=n; ++i) {
            edge[i].clear();
            step[i][0] = maxn*maxn;
            step[i][1] = maxn*maxn;
            cnt[i][0] = 0;
            cnt[i][1] = 0;
        }

        for (int i=0; i<m; ++i) {
            int u, v, w;
            scanf("%d%d%d", &u, &v, &w);
            edge[u].push_back(Node(v, w));
        }

        scanf("%d%d", &st, &ed);
        step[st][0] = 0;
        cnt[st][0] = 1;

        bfs(st);
//
//        for (int i=1; i<=n; ++i) {
//            cout << i << "==" << step[i][0] << " " << cnt[i][0] << " " << step[i][1] << " " << cnt[i][1] << endl;
//        }

        int ans = cnt[ed][0];
        if (step[ed][1] == step[ed][0] + 1) {
            ans += cnt[ed][1];
        }
        printf("%d\n", ans);
    }
    return 0;
}

/*
99
3 3
1 2 1
2 3 1
1 3 1
1 3

*/

  

时间: 2024-10-12 16:16:43

HDU 1688 Sightseeing的相关文章

hdu 1688 Sightseeing【最短路,次短路条数】

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1688 题意:求最短路和次短路条数如果次短路长度=最短路长度+1 这输出次短路条数+最短路条数,否则输出最短路条数 分析:这是到模版题,献上模版: #include<stdio.h> #include<string.h> #include<algorithm> #include<iostream> #include<queue> #include<

HDU 1688 Sightseeing 【输出最短路+次短路条数】

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1688 题目大意:给n个点,m条有向边.再给出起点s, 终点t.求出s到t的最短路条数+次短路条数. 思路: 1.最短路和次短路是紧密相连的,在最短路松弛操作中,当我们找到一条更短的路径,也就意味着之前的路径不再是最短路,而成为了次短路,利用这个关系可以实现状态的转移. 2.好久没写优先队列了,都忘记了加个 priority_queue, 这样才能写重载,才能排序. 注释在代码里: 1 #includ

hdu 1688 Sightseeing (最短路径)

Sightseeing Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 639    Accepted Submission(s): 249 Problem Description Tour operator Your Personal Holiday organises guided bus trips across the Benel

POJ 3255 &amp;&amp; HDU 1688 &amp;&amp; HDU 3191 次短路问题

POJ 3255 Roadblocks Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 7627   Accepted: 2798 Description Bessie has moved to a small farm and sometimes enjoys returning to visit one of her best friends. She does not want to get to her old h

hdu 1688

最短路与次短路条数 #include <stdio.h> #include <string.h> #define N 10005 #define INF 0x3f3f3f3f struct Edge{ int u,val,next; }e[2*N]; int p[N],vis[N][2],d[N][2],cnt[N][2]; void add(int n,int m) { int i,x,y,cost,cout = 1; for(i = 1 ; i <= n ; i++) p

【HDOJ】1688 Sightseeing

Dijkstra求解次短路径,使用cnt和dis数组记录最小.次小的个数和长度.重写更新操作. 1 /* 1688 */ 2 #include <iostream> 3 #include <string> 4 #include <map> 5 #include <queue> 6 #include <set> 7 #include <vector> 8 #include <algorithm> 9 #include <

图论 500题——主要为hdu/poj/zoj

转自——http://blog.csdn.net/qwe20060514/article/details/8112550 =============================以下是最小生成树+并查集======================================[HDU]1213   How Many Tables   基础并查集★1272   小希的迷宫   基础并查集★1325&&poj1308  Is It A Tree?   基础并查集★1856   More i

hdu图论题目分类

=============================以下是最小生成树+并查集====================================== [HDU] 1213 How Many Tables 基础并查集★ 1272 小希的迷宫 基础并查集★ 1325&&poj1308 Is It A Tree? 基础并查集★ 1856 More is better 基础并查集★ 1102 Constructing Roads 基础最小生成树★ 1232 畅通工程 基础并查集★ 123

HDU 专题分类

[背包问题] 2602 Bone Collector 1114 Piggy-Bank 1203 I NEED A OFFER! 1171 Big Event in HDU 1059 Dividing 2844 Coins 2191 悼念512汶川大地震遇难同胞--珍惜现在,感恩生活 2159 FATE 1561 The more, The Better 1011 Starship Troopers 2639 Bone Collector II 3033 I love sneakers! 2955