http://acm.hdu.edu.cn/showproblem.php?pid=1142
题意:A能走到B:A到终点的距离<B到终点的距离,求满足这种要求的最短路径的个数。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int MAX=0xfffffff;
const int NM=1005;
int a[NM][NM],dis[NM],dp[NM],n;
bool vis[NM];
void Dijkstra(int s)
{
int i,j,u,mmin;
memset(vis,0,sizeof(vis));
for(i=1;i<=n;i++) dis[i]=a[s][i];
dis[s]=0;vis[s]=true;
for(j=1;j<n;j++){
mmin=MAX;
for(i=1;i<=n;i++){
if(!vis[i] && dis[i]<mmin){
mmin=dis[i];u=i;
}
}
if(mmin==MAX) break;
vis[u]=true;
for(i=1;i<=n;i++){
if(!vis[i] && dis[u]+a[u][i]<dis[i])
dis[i]=dis[u]+a[u][i];
}
}
}
int DFS(int v){ //搜索路径
if(dp[v]) return dp[v];
if(v==2) return 1;
for(int i=1;i<=n;i++){
if(a[v][i]!=MAX && dis[v]>dis[i]){ //
dp[v]+=DFS(i);
}
}
return dp[v];
}
int main()
{
int m,i,j,x,y,vau;
while(scanf("%d",&n) && n){
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
a[i][j]=MAX;
scanf("%d",&m);
for(i=0;i<m;i++){
scanf("%d%d%d",&x,&y,&vau);
a[x][y]=a[y][x]=vau; //
}
Dijkstra(2); //找到每个点到终点的距离
memset(dp,0,sizeof(dp));
DFS(1);
printf("%d\n",dp[1]);
}
return 0;
}
http://acm.hdu.edu.cn/showproblem.php?pid=1428
分析:BFS(求出每个点到(n,n)的距离)+DFS
同上题,注意这句话:他考虑从A区域到B区域仅当存在一条从B到机房的路线比任何一条从A到机房的路线更近
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
const int NM=55;
__int64 dp[NM][NM];
int a[NM][NM],f[NM][NM],n;
int d[4][2]={-1,0,1,0,0,-1,0,1};
struct Node{
int x,y;
};
void BFS()
{
queue<Node>q1;
Node t,pt;
t.x=n;t.y=n;
f[n][n]=a[n][n];
q1.push(t);
while(!q1.empty())
{
t=q1.front();q1.pop();
if(t.x==1 && t.y==1) continue;
for(int i=0;i<4;i++){
pt.x=t.x+d[i][0];pt.y=t.y+d[i][1];
if(pt.x>0&&pt.x<=n && pt.y>0&&pt.y<=n)
{
if(f[t.x][t.y]+a[pt.x][pt.y]<f[pt.x][pt.y]){
f[pt.x][pt.y]=f[t.x][t.y]+a[pt.x][pt.y];
q1.push(pt);
}
}
}
}
}
__int64 DFS(int x,int y)
{
int i,x1,y1;
if(dp[x][y]) return dp[x][y];
if(x==n && y==n) return 1;
for(i=0;i<4;i++){
x1=x+d[i][0];y1=y+d[i][1];
if(x1<=0||x1>n || y1<=0||y1>n) continue;
if(f[x1][y1]<f[x][y]) dp[x][y]+=DFS(x1,y1);
}
return dp[x][y];
}
int main()
{
int i,j;
while(~scanf("%d",&n)){
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
scanf("%d",&a[i][j]);
memset(dp,0,sizeof(dp));
memset(f,1,sizeof(f));
BFS();
DFS(1,1);
printf("%I64d\n",dp[1][1]);
}
return 0;
}