HDU 3191 + HDU 1688(次短路)

来源:互联网 发布:程序员必备 编辑:程序博客网 时间:2024/06/04 19:48

HDU 3191:  How Many Paths Are There


题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3191


题意:求出次短路的长度和数目


思路:dis[i][0]代表到达的i点的最短路长度,dis[i][1]代表次短路长度; 

dp[i][0]代表到达i点的最短路数目,dp[i][1]代表次短路数目;

分四种情况去处理松弛情况


#include <cstdio>#include <cstring>#include <cstdlib>#include <iostream>#include <algorithm>#include <vector>#include <queue>#include <string>#include <set>#include <utility>#include <functional>#pragma comment (linker, "/STACK:1024000000,1024000000")using namespace std;const int maxn = 1010;const int inf = 0x3f3f3f3f;int cnt, head[maxn];int dis[maxn][2], dp[maxn][2], vis[maxn][2];struct node{    int u, d, fl;    node(int _u = 0, int _d = 0, int _fl = 0): u(_u), d(_d), fl(_fl) {}    bool operator < (const node &rhs) const    {        if (d != rhs.d)            return d > rhs.d;        return u > rhs.u;    }};struct edge{    int to, w, nxt;} e[maxn << 1];void init(){    cnt = 0;    memset(head, -1, sizeof(head));}void add(int u, int v, int w){    e[cnt].to = v;    e[cnt].w = w;    e[cnt].nxt = head[u];    head[u] = cnt++;}void dijkstra(int s, int t){    memset(dis, inf, sizeof(dis));    memset(dp, 0, sizeof(dp));    memset(vis, 0, sizeof(vis));    priority_queue <node> que;    dis[s][0] = 0, dp[s][0] = 1;    que.push(node(s, 0, 0));    while (!que.empty())    {        node cur = que.top();        que.pop();        int u = cur.u;        int fl = cur.fl;        if (vis[u][fl]) continue;        vis[u][fl] = true;        for (int i = head[u]; ~i; i = e[i].nxt)        {            node next;            int v = e[i].to;            int w = e[i].w;            if (!vis[v][0] && cur.d + w < dis[v][0])            {                if (dis[v][0] != inf)                {                    next.u = v, next.d = dis[v][0], next.fl = 1;                    dis[v][1] = dis[v][0];                    dp[v][1] = dp[v][0];                    que.push(next);                }                dis[v][0] = cur.d + w;                dp[v][0] = dp[u][fl];                next.u = v, next.d = dis[v][0], next.fl = 0;                que.push(next);            }            else if (!vis[v][0] && cur.d + w == dis[v][0])            {                dp[v][0] += dp[u][fl];            }            else if (!vis[v][1] && cur.d + w < dis[v][1])            {                dis[v][1] = cur.d + w;                dp[v][1] = dp[u][fl];                next.u = v, next.d = dis[v][1], next.fl = 1;                que.push(next);            }            else if (!vis[v][1] && cur.d + w == dis[v][1])            {                dp[v][1] += dp[u][fl];            }        }    }}int main(){    int n, m, start, end;    while (~scanf("%d%d%d%d", &n, &m, &start, &end))    {        init();        for (int i = 0; i < m; i++)        {            int u, v, w;            scanf("%d%d%d", &u, &v, &w);            add(u, v, w);        }        dijkstra(start, end);        printf("%d %d\n", dis[end][1], dp[end][1]);    }    return 0;}


HDU 1688:Sightseeing 


题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1688


题意:找出最短路和比最短路长1的路径数目之和


思路:和上题差不多,最后多一个判断即可


#include <cstdio>#include <cstring>#include <cstdlib>#include <iostream>#include <algorithm>#include <vector>#include <queue>#include <string>#include <set>#include <utility>#include <functional>#pragma comment (linker, "/STACK:1024000000,1024000000")using namespace std;const int maxn = 10010;const int inf = 0x3f3f3f3f;int cnt, head[maxn];int dis[maxn][2], dp[maxn][2], vis[maxn][2];struct node{    int u, d, fl;    node(int _u = 0, int _d = 0, int _fl = 0): u(_u), d(_d), fl(_fl) {}    bool operator < (const node &rhs) const    {        if (d != rhs.d)            return d > rhs.d;        return u > rhs.u;    }};struct edge{    int to, w, nxt;} e[maxn << 1];void init(){    cnt = 0;    memset(head, -1, sizeof(head));}void add(int u, int v, int w){    e[cnt].to = v;    e[cnt].w = w;    e[cnt].nxt = head[u];    head[u] = cnt++;}void dijkstra(int s, int t){    memset(dis, inf, sizeof(dis));    memset(dp, 0, sizeof(dp));    memset(vis, 0, sizeof(vis));    priority_queue <node> que;    dis[s][0] = 0, dp[s][0] = 1;    que.push(node(s, 0, 0));    while (!que.empty())    {        node cur = que.top();        que.pop();        int u = cur.u;        int fl = cur.fl;        if (vis[u][fl]) continue;        vis[u][fl] = true;        for (int i = head[u]; ~i; i = e[i].nxt)        {            node next;            int v = e[i].to;            int w = e[i].w;            if (!vis[v][0] && cur.d + w < dis[v][0])            {                if (dis[v][0] != inf)                {                    next.u = v, next.d = dis[v][0], next.fl = 1;                    dis[v][1] = dis[v][0];                    dp[v][1] = dp[v][0];                    que.push(next);                }                dis[v][0] = cur.d + w;                dp[v][0] = dp[u][fl];                next.u = v, next.d = dis[v][0], next.fl = 0;                que.push(next);            }            else if (!vis[v][0] && cur.d + w == dis[v][0])            {                dp[v][0] += dp[u][fl];            }            else if (!vis[v][1] && cur.d + w < dis[v][1])            {                dis[v][1] = cur.d + w;                dp[v][1] = dp[u][fl];                next.u = v, next.d = dis[v][1], next.fl = 1;                que.push(next);            }            else if (!vis[v][1] && cur.d + w == dis[v][1])            {                dp[v][1] += dp[u][fl];            }        }    }}int main(){    int t;    scanf("%d", &t);    while (t--)    {        init();        int n, m;        scanf("%d%d", &n, &m);        for (int i = 0; i < m; i++)        {            int u, v, w;            scanf("%d%d%d", &u, &v, &w);            add(u, v, w);        }        int start, end;        scanf("%d%d", &start, &end);        dijkstra(start, end);        if (dis[end][0] + 1 == dis[end][1])            printf("%d\n", dp[end][0] + dp[end][1]);        else            printf("%d\n", dp[end][0]);    }    return 0;}



0 0
原创粉丝点击