题目意思大致为从s开始到达其中一个任意p,求到达p所需的最小值。
这题主要有两个剪枝
第一个:需要设置一个二维数组dist记录到达某点路径长度modk的最小值
第二个:用到stl库vector,把这个换成二维数组是过不了的,每次dfs便利可以节省不少长度
做这题时充满了曲折,一开始,只是暴搜,用了点小剪枝,可是很不幸,一直超时,后来用了第一个剪枝还是超时,
当用了stl后才算把它解决掉。
#include<cstdio>
#include<cstring>
#include<vector>
using namespace std;
const int Max=1000000000;
int n,m,s,k;
int _min,pos;
bool isP[1001];
int dist[1001][1001];
struct Edge{
int v,w;
Edge(int vv,int ww):v(vv),w(ww){};
};
vector<vector<Edge> > r;
void dfs(int from,int value){
if(value<=_min&&value%k==0&&isP[from]){
if(value<_min)
{
_min=value;
pos=from;
}
if(value==_min){
pos=min(pos,from);
}
return;
}
for(int i=0;i<r[from].size();i++){
int v=r[from][i].v,w=r[from][i].w;
//printf("%d %d\n",value+r[from][i],dist[from][(value+r[from][i])%k]);
if(dist[v][(value+w)%k]==-1||(value+w)<dist[v][(value+w)%k]){
dist[v][(value+w)%k]=value+w;
dfs(v,value+w);
//printf("%d %d %d\n",from,(value+r[from][i])%k,dist[from][(value+r[from][i])%k]);
}
}
}
int main()
{
int T;
scanf("%d",&T);
for(int t=0;t<T;t++){
_min=Max;
scanf("%d%d%d%d",&n,&m,&s,&k);
memset(isP,0,sizeof(isP));
r.clear();
r.resize(n+2);
for(int k=0;k<=n;k++){
for(int j=0;j<=n;j++){
dist[k][j]=-1;
//printf("%d\n",dist[i][j]);
}
}
char is;
getchar();
for(int i=1; i<=n; i++){
scanf("%c",&is);
if(is=='P'){
isP[i]=true;
}
else
isP[i]=false;
}
int from,to,value;
for(int i=0; i<m; i++){
scanf("%d%d%d",&from,&to,&value);
r[from].push_back(Edge(to,value));
}
dfs(s,0);
printf("Case %d: ",t+1);
if(_min==Max){
printf("-1 -1\n");
}
else{
printf("%d %d\n",_min,pos);
}
}
return 0;
}