POJ1724 ROADS

解题思路:

从1开始深度优先遍历整个图,找到所有能到达N的走法,但是如果当前已经找到的最优路径长度为L,那么以后总长度已经大于L的走法就可以直接放弃。
用midL[k][m] 表示:走到城市k时总过路费为m的条件下,最优路径的长度。
若在后续的搜索中,再次走到k时,如果总路费恰好为m,且此时的路径长度已经超过midL[k][m],则不必再走下去了。

#include <iostream>
#include <vector>
#include <cstring>
using namespace std;
const int inf = 0x3f3f3f3f;
int k,n,r;
struct road{
 int e,l,c;
};
vector <vector<road> > citymap(110);
int minLen=inf;
bool visited[110];
int totalLen;
int totalCost;
int minL[110][10110];

void dfs(int s)
{
    if(s==n)
    {
        if(minLen>totalLen)
            minLen=totalLen;
        return;
    }
    for(int i=0;i<citymap[s].size();i++)
    {
        int e=citymap[s][i].e;
        if(!visited[e])
        {
            int cost=totalCost+citymap[s][i].c;
            if(cost>k)
                continue;
            if(totalLen+citymap[s][i].l>=minLen)
                continue;
            if(totalLen+citymap[s][i].l>=minL[e][cost])
                continue;
            totalLen+=citymap[s][i].l;
            totalCost=cost;
            minL[e][cost]=totalLen;
            visited[e]=1;
            dfs(e);
            visited[e]=0;
            totalLen-=citymap[s][i].l;
            totalCost-=citymap[s][i].c;
        }
    }
}
int main()
{
    cin>>k>>n>>r;
    for(int i=0;i<r;i++)
    {
        int s;
        road r;
        cin>>s>>r.e>>r.l>>r.c;
        citymap[s].push_back(r);
    }
    memset(visited,0,sizeof(visited));
    memset(minL,inf,sizeof(minL));
    totalCost=0;
    totalLen=0;
    dfs(1);
    if(minLen!=inf)
        cout<<minLen<<endl;
    else
        cout<<-1<<endl;
}

 

posted @ 2017-04-20 15:46  Kearon  阅读(179)  评论(0编辑  收藏  举报