赞
踩
本题是一部战争大片 —— 你需要从己方大本营出发,一路攻城略地杀到敌方大本营。首先时间就是生命,所以你必须选择合适的路径,以最快的速度占领敌方大本营。当这样的路径不唯一时,要求选择可以沿途解放最多城镇的路径。若这样的路径也不唯一,则选择可以有效杀伤最多敌军的路径。
输入第一行给出 2 个正整数 N(2 ≤ N ≤ 200,城镇总数)和 K(城镇间道路条数),以及己方大本营和敌方大本营的代号。随后 N-1 行,每行给出除了己方大本营外的一个城镇的代号和驻守的敌军数量,其间以空格分隔。再后面有 K 行,每行按格式城镇1 城镇2 距离
给出两个城镇之间道路的长度。这里设每个城镇(包括双方大本营)的代号是由 3 个大写英文字母组成的字符串。
按照题目要求找到最合适的进攻路径(题目保证速度最快、解放最多、杀伤最强的路径是唯一的),并在第一行按照格式己方大本营->城镇1->...->敌方大本营
输出。第二行顺序输出最快进攻路径的条数、最短进攻距离、歼敌总数,其间以 1 个空格分隔,行首尾不得有多余空格。
- 10 12 PAT DBY
- DBY 100
- PTA 20
- PDS 90
- PMS 40
- TAP 50
- ATP 200
- LNN 80
- LAO 30
- LON 70
- PAT PTA 10
- PAT PMS 10
- PAT ATP 20
- PAT LNN 10
- LNN LAO 10
- LAO LON 10
- LON DBY 10
- PMS TAP 10
- TAP DBY 10
- DBY PDS 10
- PDS PTA 10
- DBY ATP 10

- PAT->PTA->PDS->DBY
- 3 30 210
这题的大体方法和L2紧急救援是差不多的,只是建图和深搜要注意一些,首先建图的话,我是默认将本方大本营存到0号下标的字符数组中,其他地方在输入的时候也存到字符数组中,至于驻守的敌军数量可以对应存到相应下标的整形数组中,所以,一个地方就对应一个下标,然后可以通过这些下标来建图,然后先通过Dijkstra 算法来找到最短路径,然后在深搜,如果路径超过最短路径就返回,如果到达敌方大本营就先判断解放城市有没有大于等于之前的,如果等于在判断消灭消灭的敌军有没有大于之前的,如果大于就将沿途经过的城市记下来,然后更改相应数据,如果解放城市大于之前的就直接记录城市,然后更改数据。大体思路是这样,具体就看代码把。
- #include <iostream>
- #include <stdio.h>
- #include <string.h>
- using namespace std;
- char x[203][5];
- int a[203],z[203][203],z1[203][203],flag[203],flag1;
- int t1[203],t2[203],lennum=0,all,min1=9999,min2=-1,min3=-1;
- void djks(int b)
- {
- flag[0]=1;
- for(int n=0;n<b-1;n++)
- {
- int mi=999999;
- int t;
- for(int m=0;m<b;m++)
- {
- if(z1[0][m]<mi&&flag[m]==0)
- {
- mi=z1[0][m];
- t=m;
- }
- }
- flag[t]=1;
- if(t==flag1)
- {
- min1=mi;
- return;
- }
- else
- {
- for(int m=0;m<b;m++)
- {
- if(z1[0][t]+z1[t][m]<z1[0][m]&&flag[m]==0)
- {
- z1[0][m]=z1[0][t]+z1[t][m];
- }
- }
- }
- }
- }
- void dfs(int start,int num,int len,int num1,int num2)
- {
- if(len>min1)
- {
- return;
- }
- if(start==flag1)
- {
- lennum++;
- if(num1>=min2)
- {
- if(num1==min2)
- {
- if(num2>min3)
- {
- min3=num2;
- for(int m=0;m<num1;m++)
- {
- t1[m]=t2[m];
- }
- all=num1;
- }
- }
- else
- {
- min3=num2;
- for(int m=0;m<num1;m++)
- {
- t1[m]=t2[m];
- }
- all=num1;
- }
- min2=num1;
- }
- else
- {
- return;
- }
- }
- for(int n=0;n<num;n++)
- {
- if(z[start][n]!=-1&&flag[n]==0)
- {
- flag[n]=1;
- t2[num1]=n;
- dfs(n,num,len+z[start][n],num1+1,num2+a[n]);
- flag[n]=0;
- }
- }
- }
- int main(int argc, char *argv[]) {
- int b,c,d,e;
- char x1[5],x2[5],x3[5],x4[5];
- scanf("%d %d %s %s",&b,&c,x1,x2);
- for(int n=0;n<b;n++)
- {
- for(int m=0;m<b;m++)
- {
- z1[n][m]=999999;
- z[n][m]=-1;
- }
- }
- strcpy(x[0],x1);
- for(int n=1;n<b;n++)
- {
- scanf("%s %d",x[n],&a[n]);
- if(strcmp(x[n],x2)==0)
- {
- flag1=n;
- }
- }
- for(int n=0;n<c;n++)
- {
- scanf("%s %s %d",x3,x4,&e);
- int m1,m2;
- for(m1=0;m1<b;m1++)
- {
- if(strcmp(x[m1],x3)==0)
- {
- for(m2=0;m2<b;m2++)
- {
- if(strcmp(x[m2],x4)==0)
- {
- z[m1][m2]=e;
- z[m2][m1]=e;
- z1[m1][m2]=e;
- z1[m2][m1]=e;
- break;
- }
- }
- break;
- }
- }
- }
- djks(b);
- memset(flag,0,sizeof(flag));
- dfs(0,b,0,0,0);
- printf("%s",x1);
- for(int n=0;n<all;n++)
- {
- printf("->%s",x[t1[n]]);
- }
- printf("\n");
- printf("%d %d %d\n",lennum,min1,min3);
- return 0;
- }

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。