题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2437
参考博文:http://blog.csdn.net/u013167299/article/details/47358245
#include <iostream> #include <vector> #include <cstring> using namespace std; #define N 1005 //对应题目的n、m、s、k int n,m,s,k; //对应洞穴的类型 char kinds[N]; //node 图节点类型 struct node{ int to,len; }; //图 vector< vector<node> > G; //用于剪枝 int mod[N][N]; //ans 存放结果 //destination 记录目的地 long long ans; int destination; //深度优先遍历 //n当前所在节点 //sum 当前走过的路径长度 void dfs(int n,long long sum){ //如果sum不是初始值,并且当前走过的路径长度sum 小于 ans if(ans!=-1&&sum>ans) return; //判断洞穴类型以及路径长度是否符合要求 if(kinds[n]=='P'&&sum%k==0){ if(ans==-1||ans>sum){ ans=sum; destination=n; }else if(ans==sum&&destination>n) destination=n; return; } //以n为基点,遍历其邻接点 int max=G[n].size(); for(int i=0;i<max;i++){ int to=G[n][i].to; int dis=sum+G[n][i].len; //如果多次到达一个顶点的话,而且余数又相同,那么保留距离小的 if(mod[to][dis%k]!=-1&&mod[to][dis%k]<=dis) continue; mod[to][dis%k]=dis; dfs(to,dis); } } int main(){ int T; cin>>T; for(int t=1;t<=T;t++){ cin>>n>>m>>s>>k; for(int i=1;i<=n;i++) cin>>kinds[i]; //重置图等相关数据 ans=-1; destination=-1; G.clear(); G.resize(n+2); memset(mod,-1,sizeof(mod)); int x; node p; for(int i=1;i<=m;i++){ cin>>x>>p.to>>p.len; G[x].push_back(p); } dfs(s,0); cout<<"Case "<<t<<": "<<ans<<" "<<destination<<endl; } return 0; }