5 6 1 3 2 1 4 2 3 4 3 1 5 12 4 2 34 5 2 24 7 8 1 3 1 1 4 1 3 7 1 7 4 1 7 5 1 6 7 1 5 2 1 6 2 1 0
2 4
没有过英语四级的渣渣 果然不能做这道题。。
理解为求最短路径的个数了 。主要就是看这句话He considers taking a path from A to B to be progress if there exists a route from B to his home that is shorter than any possible route from A. 大概意思就是 如果A-B有路 并且我想从A走到B那么有条件就是A到2的距离要大于B到2的距离
思路:
1.digkstra算法求出各点到2-1的最短距离 同时存贮其它点到2的最短距离
2.记忆化搜索 从1开始 找到符合条件的路径数
#include <stdio.h> #include <vector> #include <string.h> #include <queue> #include <algorithm> using namespace std; int min_path; int min_count; //存贮当前点到2的最短路径 int dis[1005]; //记忆化搜索时存贮路径数 int dp[1005]; int n; //digkstra算法和记忆化搜索时 判断是否已经走过某点 bool vis[1005]; struct node { int pos; int cost; bool friend operator<(node x,node y) { return x.cost>y.cost; } }; //存贮边 vector<node>map[1005]; int digkstra(int x) { priority_queue<node>s; memset(vis,false,sizeof(vis)); memset(dis,100,sizeof(dis)); node temp,temp1; temp.pos=x;temp.cost=0; s.push(temp); while(!s.empty()) { temp=temp1=s.top();s.pop(); vis[temp.pos]=true; dis[temp.pos]=min(dis[temp.pos],temp.cost); if(temp.pos==1) return temp.cost; for(int i=0;i<map[temp.pos].size();i++) { int x=map[temp.pos][i].pos; int y=map[temp.pos][i].cost; if(!vis[x]) { temp.pos=x; temp.cost+=y; s.push(temp); } temp=temp1; } } return -1; } //记忆化搜索 int dfs(int pos,int sum) { if(dp[pos]) return dp[pos]; if(pos==2) return 1; int result=0; for(int i=0;i<map[pos].size();i++) { int x=map[pos][i].pos; int y=map[pos][i].cost; //pos->x有路 并且满足pos到2的最短路径大于x到2的最短路径 if(!vis[x]&&dis[pos]>dis[x]) { vis[x]=true; result+=dfs(x,sum+y); vis[x]=false; } } dp[pos]=result; return dp[pos]; } int main() { while(~scanf("%d",&n)&&n) { int m; scanf("%d",&m); memset(map,0,sizeof(map)); for(int i=0;i<m;i++) { int a,b,x; scanf("%d %d %d",&a,&b,&x); node temp; temp.pos=b;temp.cost=x; map[a].push_back(temp); temp.pos=a; map[b].push_back(temp); } min_path=digkstra(2); min_count=0; memset(vis,false,sizeof(vis)); memset(dp,0,sizeof(dp)); vis[1]=true; printf("%d\n",dfs(1,0)); } return 0; }