L3-011 直捣黄龙 (最短路径)

本题是一部战争大片 —— 你需要从己方大本营出发,一路攻城略地杀到敌方大本营。首先时间就是生命,所以你必须选择合适的路径,以最快的速度占领敌方大本营。当这样的路径不唯一时,要求选择可以沿途解放最多城镇的路径。若这样的路径也不唯一,则选择可以有效杀伤最多敌军的路径。

输入格式:

输入第一行给出 2 个正整数 N(2 ≤ N ≤ 200,城镇总数)和 K(城镇间道路条数),以及己方大本营和敌方大本营的代号。随后 N-1 行,每行给出除了己方大本营外的一个城镇的代号和驻守的敌军数量,其间以空格分隔。再后面有 K 行,每行按格式城镇1 城镇2 距离给出两个城镇之间道路的长度。这里设每个城镇(包括双方大本营)的代号是由 3 个大写英文字母组成的字符串。

输出格式:

按照题目要求找到最合适的进攻路径(题目保证速度最快、解放最多、杀伤最强的路径是唯一的),并在第一行按照格式己方大本营->城镇1->...->敌方大本营输出。第二行顺序输出最快进攻路径的条数、最短进攻距离、歼敌总数,其间以 1 个空格分隔,行首尾不得有多余空格。

输入样例:

#include 
#include 
#include 
#include 
#include 
#include 
#define INF 0x3f3f3f3f
#define maxn 205
using namespace std;
stack sta;
int cnt = 0;
int n, k;
string s, e;   //起点,终点 
int g[maxn][maxn];  //图 
int v[maxn];   //i的敌人数量 
int dis[maxn];  //到i的最小距离 
int dv[maxn], dn[maxn]; //到i的最大歼敌数,到i的最大解放城镇数 
void dfs1(int x) //求唯一路径 
{sta.push(x);if(x == 1)return;for(int i = 1; i <= n; i ++){if(g[x][i] != INF && dis[x] - dis[i] == g[x][i] && dv[x] - dv[i] == v[x] && dn[x] - dn[i] == 1){dfs1(i);break;}}
}
void dfs2(int x) //求最短路数量 
{if(x == 1){cnt ++;return;}for(int i = 1; i <= n; i ++){if(i != x && g[x][i] != INF && dis[x] - dis[i] == g[x][i]){dfs2(i);}}
}
int main()
{cin >> n >> k >> s >> e;map m;memset(dv, 0, sizeof(dv));memset(dn, 0, sizeof(dn));for(int i = 1; i <= n; i ++){for(int j = 1; j <= n; j ++)g[i][j] = INF;g[i][i] = 0;}m[s] = 1; //起点为1 int t;  //终点 string str[maxn];str[1] = s;for(int i = 2; i <= n; i ++){string strr;int w;cin >> strr >> w;v[i] = w;m[strr] = i;str[i] = strr;if(strr == e)t = i;}for(int i = 0; i < k; i ++){string x, y;int d;cin >> x >> y >> d;g[m[x]][m[y]] = d;g[m[y]][m[x]] = d;}for(int i = 1; i <= n; i ++){dis[i] = g[1][i];if(i != 1 && g[1][i] != INF){dv[i] = v[i];dn[i] = 1;}}	bool vis[maxn] = {0};vis[1] = true;for(int i = 1; i < n; i ++){int minn = INF;int k;for(int j = 1; j <= n; j ++){if(!vis[j] && minn > dis[j]){minn = dis[j];k = j;}}vis[k] = true;for(int j = 1; j <= n; j ++){if(!vis[j] && g[k][j] != INF){if(dis[k] + g[k][j] < dis[j]){dis[j] = dis[k] + g[k][j];dv[j] = dv[k] + v[j];dn[j] = dn[k] + 1;}else if(dis[k] + g[k][j] == dis[j]){if(dn[j] < dn[k] + 1){dv[j] = dv[k] + v[j];dn[j] = dn[k] + 1;}else if(dn[j] == dn[k] + 1){dv[j] = max(dv[j], dv[k] + v[j]);}}}		}}dfs1(t);bool first = true;while(!sta.empty()){int top = sta.top();sta.pop();if(first)first = false;elsecout << "->";cout << str[top];}cout << endl;dfs2(t);cout << cnt << " " << dis[t] << " " << dv[t] << endl;return 0;
}

 


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部