最短路径 | 1018
在理解错题意的情况下得了25分:
题意:
If there are more than one shortest path, the one that requires the least number of bikes sent from PBMC will be chosen.
意思是在路径最短的情况下,选择一条sent(发送)单车最少的路径。
但是这就结束了吗?naive。请看在output要求中的一句话:
output the one that requires minimum number of bikes that we must take back to PBMC.
在路径不唯一的情况下,take back(送回)PBMC的单车要求最小。
在这样错误的理解下,我理解为送出或送回其中一个为1,只需要用公式计算 best_val= (cnt)*Cmax/2-bk ,要求 best_val 最小即可。这是错误的。
比如一个顶点最优的点权为5,(0)→(0)→(9),这种情况下需要发送14辆单车,送回4辆。
25分代码:
#include <stdio.h> #include <memory.h> #include <math.h> #include <string> #include <vector> #include <set> #include <stack> #include <queue> #include <algorithm> #include <map> #define I scanf #define OL puts #define O printf #define F(a,b,c) for(a=b;a<c;a++) #define FF(a,b) for(a=0;a<b;a++) #define FG(a,b) for(a=b-1;a>=0;a--) #define LEN 1010 #define MAX (1<<30)+1 #define V vector<int> using namespace std; int g[LEN][LEN]; int vis[LEN]; vector<int> path; vector<int> ansPath; int best_val=MAX; int bike[LEN]; int n,Cmax,Sp; int bestCost=MAX; void dfs(int s,int bk,int cost,int cnt){ if(s==Sp){ if(cost<bestCost){ bestCost=cost; ansPath=path; ansPath.push_back(s); }else if(cost==bestCost){ int val= (cnt)*Cmax/2-bk ; if( abs(val)<abs(best_val) ){ best_val=val; ansPath=path; ansPath.push_back(s); } } return; } for(int i=1;i<=n;i++) if(g[s][i] && !vis[i] && cost<bestCost){ vis[s]=1; path.push_back(s); dfs(i,bk+bike[i],cost+g[s][i],cnt+1); path.pop_back(); vis[s]=0; } } int main(){ // freopen("D:\\CbWorkspace\\PAT\\最短路径\\1018.txt","r",stdin); int m,i,j,a,b,w; I("%d%d%d%d",&Cmax,&n,&Sp,&m); F(i,1,n+1){ I("%d",&bike[i]); } F(i,1,m+1){ I("%d%d%d",&a,&b,&w); g[a][b]=w; g[b][a]=w; } vis[0]=1; dfs(0,0,0,0); // ansPath.insert(ansPath.begin(),0); O("%d ",best_val>0?best_val:0); FF(i,ansPath.size()){ printf("%d",ansPath[i]); if(i!=ansPath.size()-1) O("->"); } O(" %d",best_val<0?-best_val:0); // O("%d",) return 0; }