pat 1003 Emergency (值得重点回顾)

来源:互联网 发布:java文件上传到数据库 编辑:程序博客网 时间:2024/05/17 16:46

一开始看错题意,题意是要求单源点对最短路径数和最大的点权重之和。知道要用dijskra算法,但为了求最短路径数,还得用深搜,依次把点加入集合中,若路径长度=最短路径值时,路径数+1。同时求出最大的点权重之和。

递归函数{
出口条件处理(最低级的情况);
return ...;
从第1列的8个位置{
依次尝试设置格子及限制区域
向下级递归
复原上一次尝试
}
};


AC代码:

#include<iostream>using namespace std;const int INF=1000000;const int NUM=505;int map[NUM][NUM];int team[NUM],isVisit[NUM];int dist[NUM];int ans,maxTeamNum;void init(){int i,j;for(i=0;i<NUM;i++){isVisit[i]=0;team[i]=0;dist[i]=INF;for(j=0;j<NUM;j++){if(j!=i){map[i][j]=INF;//初始化为无穷大,表示不连通map[j][i]=INF;}}}}void dijskra(int n,int source){int i,minDis=INF,index=0,j;for(i=0;i<n;i++){dist[i]=map[source][i];}isVisit[source]=1;//将其加入已访问点的集合for(i=0;i<n-1;i++){minDis=INF;index=0;for(j=0;j<n;j++){if(!isVisit[j]&&dist[j]<minDis){//找到最小距离点minDis=dist[j];index=j;}}isVisit[index]=1;//将其加入已访问点的集合for(j=0;j<n;j++){//更新源点与每个点之间的距离if(map[index][j]<INF&&dist[j]>dist[index]+map[index][j])dist[j]=dist[index]+map[index][j];}}}void dfs(int n,int cId,int dest,int curDis,int curTeamNum){int i;isVisit[cId]=1;if(cId==dest){if(curDis==dist[dest]){ans++;//最短路径数+1if(curTeamNum>maxTeamNum)maxTeamNum=curTeamNum;}return;} if(curDis>dist[dest])//当前的路径长度已经超过最短路径,就没有必要继续搜索了。return;for(i=0;i<n;i++){if(!isVisit[i]&&map[cId][i]<INF){//城市i未被访问过,且cId到i连通dfs(n,i,dest,curDis+map[cId][i],curTeamNum+team[i]);isVisit[i]=0;}}}int main(){int n,m,source,dest,i;int c1,c2,l;freopen("C:\\Documents and Settings\\Administrator\\桌面\\input.txt","r",stdin);cin>>n>>m>>source>>dest;init();for(i=0;i<n;i++)cin>>team[i];for(i=0;i<m;i++){cin>>c1>>c2>>l;map[c1][c2]=l;map[c2][c1]=l;}dijskra(n,source);for(i=0;i<n;i++)isVisit[i]=0;dfs(n,source,dest,0,team[source]);cout<<ans<<" "<<maxTeamNum<<endl;return 0;}

DFS递归的基本套路:



原创粉丝点击