您的位置:首页 > 其它

Poj 1724 Roads(DFS 可行性剪枝 最优性剪枝 向量)

2017-12-13 20:06 423 查看
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<vector>
using namespace std;

struct Roads
{
int d;
int l;
int t;
};

vector<Roads> city[105];    //定义向量,相当于一个二维数组,其中第一维的长度无限大,第二维的长度是105,数组中的各个元素是之前定义的Roads结构体

int K,N,R;
int totallen,totalcost,minlen;
int minn[105][10005];    //minn[i][j]表示到达i城市且花费了j时所走的最小路程 ,用于下面每走到一个城市都可以进行剪枝
int visited[105];       //由于本题是求最短路径长度,而若是走的过程中,对一个城市走了不止一遍,那么肯定不再是最短路径长度,所以每一个城市都不可以重复走

void dfs( int c )
{
if( c == N )   //走到了终点
{
minlen = min( minlen , totallen );  //结束递归之前,先更新minlen的值
return ;
}
int rnum = city[c].size();
for( int i = 0 ; i < rnum ; ++i )   //遍历c城市所能走的所有路
{
if( visited[city[c][i].d] || totalcost + city[c][i].t > K )   //可行性剪枝
continue;
if( totallen + city[c][i].l >= minlen || totallen + city[c][i].l >= minn[city[c][i].d][totalcost + city[c][i].t] )  //最优性剪枝
continue;
totalcost += city[c][i].t;
totallen += city[c][i].l;
minn[city[c][i].d][totalcost] = totallen;
visited[city[c][i].d] = 1;   //更新状态
dfs(city[c][i].d);
totallen -=  city[c][i].l;
totalcost -= city[c][i].t;
visited[city[c][i].d] = 0;   //还原状态
}
}

int main()
{
freopen( "E:\\in.txt", "r" , stdin );
cin >> K;   //总共的钱
cin >> N >> R;
for(int i = 0; i < R ; ++i)   //构建图(连接表)
{
int s;
cin>>s;
Roads r;
cin>>r.d>>r.l>>r.t;
city[s].push_back(r);
}
totalcost = 0;  //初始化
totallen = 0;
minlen = 1 << 30;
for(int i = 0 ; i < 105 ; ++i)
for(int j = 0 ; j < 10005 ; ++j)
minn[i][j] = 1 << 30;
memset(visited,0,sizeof(visited));
dfs(1);    //深搜开始
if(minlen == 1 << 30)    //minlen的值没有被改变 说明并没有找到合适的路
cout << "-1" << endl;
else
cout << minlen << endl;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: