1003. Emergency (25)

来源:互联网 发布:彩票平台源码程序 编辑:程序博客网 时间:2024/05/17 00:52

分析:求最短路径的条数,以及最短路径中点权和最大的那条路径的点权之和。Dijkstra+DFS即可

官网测试点中坑点:
1、最短路径条数不等于目标节点的入度
2、存在起点和终点相同的情况,若代码写的挫,需要特判。。

代码:

#include <cstdio>#include <vector>#include <cstring>using namespace std;const int maxv = 500+5;const int INF = 1<<28;int G[maxv][maxv];bool vis[maxv];int d[maxv];int weight[maxv];vector<int> pre[maxv];int n, m;int st, ed;int ans, num;void Dij(int s) {    memset(vis, 0, sizeof(vis));    fill(d, d+maxv, INF);    for(int i = 0; i < n; ++i)        pre[i].push_back(i);    d[s] = 0;    for(int i = 0; i < n; ++i) {        int u = -1, MIN = INF;        for(int j = 0; j < n; ++j) {            if(vis[j] == false && d[j] < MIN) {                u = j;                MIN = d[j];            }        }        if(u == -1) return;        vis[u] = true;        for(int v = 0; v < n; ++v) {            if(vis[v] == false && G[u][v] != INF) {                if(d[u]+G[u][v] < d[v]) {                    d[v] = d[u]+G[u][v];                    pre[v].clear();                    pre[v].push_back(u);                }                else if(d[u]+G[u][v] == d[v]) {                    pre[v].push_back(u);                }            }        }    }}void DFS(int v, int sum) {    if(v == st) {        ans = max(ans, sum);        num++;        return;    }    for(int i = 0; i < pre[v].size(); ++i) {        int u = pre[v][i];        DFS(u, sum+weight[u]);    }}int main() {    scanf("%d %d %d %d", &n, &m, &st, &ed);    for(int i = 0; i < n; ++i)        scanf("%d", &weight[i]);    fill(G[0], G[0]+maxv*maxv, INF);    for(int i = 0; i < m ; ++i) {        int u, v, val;        scanf("%d %d %d", &u, &v, &val);        G[u][v] = val;        G[v][u] = val;    }    Dij(st);    ans = 0, num = 0;    for(int i = 0; i < pre[ed].size(); ++i) {        int u = pre[ed][i];        DFS(u, weight[ed]+weight[u]);    }    if(st == ed) ans = weight[ed];    printf("%d %d\n", num, ans);    return 0;}

下面是不用特判的。先找出最优路径再求点权和。

#include <cstdio>#include <vector>#include <cstring>using namespace std;const int maxv = 500+5;const int INF = 1<<28;int G[maxv][maxv];bool vis[maxv];int d[maxv];int weight[maxv];vector<int> pre[maxv];vector<int> path, temp_path;int optval;int n, m;int st, ed;int ans, num;void Dij(int s) {    memset(vis, 0, sizeof(vis));    fill(d, d+maxv, INF);    for(int i = 0; i < n; ++i)        pre[i].push_back(i);    d[s] = 0;    for(int i = 0; i < n; ++i) {        int u = -1, MIN = INF;        for(int j = 0; j < n; ++j) {            if(vis[j] == false && d[j] < MIN) {                u = j;                MIN = d[j];            }        }        if(u == -1) return;        vis[u] = true;        for(int v = 0; v < n; ++v) {            if(vis[v] == false && G[u][v] != INF) {                if(d[u]+G[u][v] < d[v]) {                    d[v] = d[u]+G[u][v];                    pre[v].clear();                    pre[v].push_back(u);                }                else if(d[u]+G[u][v] == d[v]) {                    pre[v].push_back(u);                }            }        }    }}void DFS(int v) {    if(v == st) {        temp_path.push_back(v);        int value = 0;        for(int i = temp_path.size()-1; i >= 0; --i) {            int id = temp_path[i];            value += weight[id];        }        if(value > optval) {            optval = value;            path = temp_path;        }        num++;        temp_path.pop_back();        return;    }    temp_path.push_back(v);    for(int i = 0; i < pre[v].size(); ++i) {        DFS(pre[v][i]);    }    temp_path.pop_back();}int main() {    scanf("%d %d %d %d", &n, &m, &st, &ed);    for(int i = 0; i < n; ++i)        scanf("%d", &weight[i]);    fill(G[0], G[0]+maxv*maxv, INF);    for(int i = 0; i < m ; ++i) {        int u, v, val;        scanf("%d %d %d", &u, &v, &val);        G[u][v] = val;        G[v][u] = val;    }    Dij(st);    ans = 0, num = 0;    DFS(ed);    for(int i = 0; i < path.size(); ++i)        ans += weight[path[i]];    printf("%d %d\n", num, ans);    return 0;}
0 0
原创粉丝点击