L3-011 直搗黃龍 (30分)&L3-007 天梯地圖 (30分)(最短路)

L3-011 直搗黃龍 (30分)
本題是一部戰爭大片 —— 你需要從己方大本營出發,一路攻城略地殺到敵方大本營。首先時間就是生命,所以你必須選擇合適的路徑,以最快的速度佔領敵方大本營。當這樣的路徑不唯一時,要求選擇可以沿途解放最多城鎮的路徑。若這樣的路徑也不唯一,則選擇可以有效殺傷最多敵軍的路徑。

輸入格式:
輸入第一行給出 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

寫完代碼開始瘋狂wa第二個和第三個測試點,改了又改還是解決不了,最後發現是路徑的條數錯了,這裏和傳統的最短路不同的是如果在隊列裏取出的點已經被標記過了,不是直接continue,而是在下面循環的時候continue,否則的話有的點會被漏掉,直接求最短距離的話這個可以忽略。第二三個測試點可以試試下面這個樣例。
輸入樣例

5 7 a b
b 100
c 10
d 10
e 10

a b 20
a c 5
c d 5
d e 5
e b 5
a e 15
a d 10

輸出樣例

a->c->d->e->b
4 20 130

另外學到了前驅節點保存路徑。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
#include<map>
using namespace std;
const int N=110000;
const int inf=0x3f3f3f3f;
struct node{
	int id,value;
	string name;
}s[205];
struct node1{
	int to,next,value;
}s1[N];
pair<int,int>p1;
string start,endd;
map<string,int>mp;
vector<int>stk;
int head[N],num,dis[205][3],vis[205],ans,st=0,en,flag=0,pre[N];
//vis路程,節點,殺傷 
void add(int u,int v,int w){
	s1[++num]=(node1){v,head[u],w};
	head[u]=num;
}
void bfs(){
	priority_queue< pair<int,int> >q;
	en=mp[endd];
	memset(dis,0,sizeof(dis));
	for(int i=0;i<204;i++){
		dis[i][0]=inf;
	}
	dis[st][0]=0;
	pre[st]=-1;
	q.push(make_pair(0,st));
	while(!q.empty()){
		int x=q.top().second;
		q.pop();
	//	if(vis[x]) continue;
		vis[x]=1;
		for(int i=head[x]; i; i=s1[i].next){
			int to=s1[i].to,value=s1[i].value;
			if(vis[to]) continue;
			if(dis[to][0]>dis[x][0]+value){
				dis[to][0]=dis[x][0]+value;
				dis[to][1]=dis[x][1]+1;
				dis[to][2]=dis[x][2]+s[to].value;
				if(to==en)ans=1;
				pre[to]=x;
				q.push(make_pair(-dis[to][0],to));
			}
			else if(dis[to][0]==dis[x][0]+value) {	
				if(to==en)ans++;	
				q.push(make_pair(-dis[to][0],to));
				if(dis[to][1]<dis[x][1]+1){
					dis[to][1]=dis[x][1]+1;
					dis[to][2]=dis[x][2]+s[to].value;
					pre[to]=x;
				//	q.push(make_pair(-dis[to][0],to));
				}
				else if(dis[to][1]==dis[x][1]+1&&dis[to][2]<dis[x][2]+s[to].value){
					dis[to][2]=dis[x][2]+s[to].value;
					pre[to]=x;
				//	q.push(make_pair(-dis[to][0],to));
				}
			}						
		}
	}
}
void dfs(int x){
	if(x==-1) return;
	dfs(pre[x]);
	cout<<s[x].name;	
	if(x!=en) cout<<"->";
}
int main()
{
	int n,k,i,v;
	string x,y;
	cin>>n>>k>>start>>endd;
	s[0]=(node){0,0,start};
	mp[start]=0;
	for(i=1;i<n;i++){
		s[i].id=i;
		cin>>s[i].name>>s[i].value;
		mp[s[i].name]=i;
	}
	while(k--){
		cin>>x>>y>>v;
		int xx=mp[x],yy=mp[y];
		add(xx,yy,v);
		add(yy,xx,v);
	}
	
	bfs();
	dfs(en);
	
	printf("\n%d %d %d",ans,dis[en][0],dis[en][2]);
	return 0;
}

L3-007 天梯地圖 (30分)
同上最短路,開始dfs最後一個點怎麼也過不了,填坑了

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
#include<map>
using namespace std;
const int inf=0x3f3f3f3f;
typedef long long ll;
const int N=505;
vector<int>v[N];
int a[N][N][2];
int n,s1[N],s2[N],vis[N],dis1[N],dis2[N],top,y,pre1[N],pre2[N],d2[N],d3[N];
vector<int>ve[2];
void bfs1(int x){
	priority_queue< pair<int,int> >q;
	q.push(make_pair(0,x));
	memset(dis1,inf,sizeof(dis1));
	vis[x]=1;dis1[x]=0;
	while(!q.empty()){
		int t = q.top().second;
		q.pop();
	//	if(vis[t]) continue;
		vis[t]=1;
		for(int i=0;i<v[t].size();i++){
			int to=v[t][i];
			if(vis[to]) continue;
			if(dis1[to]>dis1[t]+a[t][to][1]){
				dis1[to]=dis1[t]+a[t][to][1];
				d2[to]=d2[N]+a[t][to][0];
				d3[to]=d3[t]+1;
				q.push(make_pair(-dis1[to],to));
				pre1[to]=t;
			}
			else if(dis1[to]==dis1[t]+a[t][to][1]){
				if(d2[to]>d2[t]+a[t][to][0]){
					d2[to]=d2[N]+a[t][to][0];
					d3[to]=d3[t]+1;
					q.push(make_pair(-dis1[to],to));
					pre1[to]=t;
				}
				else if(d2[to]==d2[t]+a[t][to][0]&&d3[to]>d3[t]+1){
					d3[to]=d3[t]+1;
					q.push(make_pair(-dis1[to],to));
					pre1[to]=t;
				}
			}
		}
	}
}
void bfs2(int x){
	priority_queue< pair<int,int> >q;
	q.push(make_pair(0,x));
	memset(vis,0,sizeof(vis));
	memset(d3,0,sizeof(d3));
	memset(dis2,inf,sizeof(dis2));
	vis[x]=1;dis2[x]=0;
	while(!q.empty()){
		int t = q.top().second;
		q.pop();
	//	if(vis[t]) continue;
		vis[t]=1;
		for(int i=0;i<v[t].size();i++){
			int to=v[t][i];
			if(vis[to]) continue;
			if(dis2[to]>dis2[t]+a[t][to][0]){
				dis2[to]=dis2[t]+a[t][to][0];
				d3[to]=d3[t]+1;
				q.push(make_pair(-dis2[to],to));
				pre2[to]=t;
			}
			else if(dis2[to]==dis2[t]+a[t][to][0]&&d3[to]>d3[t]+1){
				d3[to]=d3[t]+1;
				q.push(make_pair(-dis2[to],to));
				pre2[to]=t;
			}
		}
	}
}
void dfs1(int x){
	if(x==-1) return;
	dfs1(pre1[x]);
	ve[0].push_back(x);
}
void dfs2(int x){
	if(x==-1) return;
	dfs2(pre2[x]);
	ve[1].push_back(x);
}
int main()
{
	int m,i,j,x,y,t,len,time;
//	memset(a,inf,sizeof(a));
	scanf("%d %d",&n,&m);
	while(m--){
		scanf("%d %d %d %d %d",&x,&y,&t,&len,&time);
		a[x][y][0]=len;a[x][y][1]=time;
		v[x].push_back(y);
		if(!t){
			a[y][x][0]=len;a[y][x][1]=time;
			v[y].push_back(x);
		} 
	}
	scanf("%d %d",&x,&y);
	pre1[x]=pre2[x]=-1;
	bfs1(x);dfs1(y);
	bfs2(x);dfs2(y);
	printf("Time = %d",dis1[y]);
	int l1=ve[0].size();
	int l2=ve[1].size();	
	int flag=0;
	if(l1!=l2) flag=1;
	else {
		for(i=0;i<l1;i++){
			if(ve[0][i]!=ve[1][i]){
				flag=1;break;
			}
		}
	}
	if(flag){
		printf(": %d",x);
		for(i=1;i<l1;i++)
			printf(" => %d",ve[0][i]);
		printf("\n");
	}
	else printf("; ");
	printf("Distance = %d: %d",dis2[y],x);
	for(i=1;i<l2;i++) 
		printf(" => %d",ve[1][i]);
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章