题意:有N个城市,R条路,每条路有花费和长度两个特性,求从城市1到城市N的花费不超过K的最短路。
题解:
- 易知最佳路径是不可能有环路的,所以使用最基本DFS,加入访问标记数组即可。
- BFS,利用二维状态数组dp[i][j]记录到第i城市花费j的最短路径,当这个值更新时,利用其不断更新其他城市的状态。
DFS:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define INF 0X7FFFFFFF
class node
{
public:
int adjx;
int len;
int toll;
node* next;
};
class adjList
{
public:
node** adj;
adjList(int n):adj(new node*[n])
{
memset(adj,0,sizeof(node*)*(n));
}
int adjInsert(int nodeNo,int adjx,int len,int toll)
{
node* newNode = new node;
newNode->adjx = adjx;
newNode->len = len;
newNode->toll = toll;
newNode->next = adj[nodeNo];
adj[nodeNo] = newNode;
return 0;
}
};
class solve
{
private:
int K,N,R;
char* vis;
adjList* g;
int minLen;
public:
solve(int k,int n,int r):K(k),N(n),R(r),minLen(INF)
{
g = new adjList(N+1);
vis = new char[N+1];
memset(vis,0,sizeof(char)*(N+1));
processIn();
DFS(1,0,0);
printf("%d\n",minLen == INF?-1:minLen);
}
~solve()
{
delete[] g;
delete[] vis;
}
int processIn();
int DFS(int u,int len,int cost);
};
int solve::DFS(int u,int len,int cost)
{
vis[u] = 1;
if(u == N)
{
if(cost <= K&&len < minLen)
{
minLen = len;
}
return 0;
}
if(len >= minLen||cost > K)
return 0;
int v;
node* tmpNode;
for(tmpNode = g->adj[u];tmpNode != NULL;tmpNode = tmpNode->next)
{
v = tmpNode->adjx;
if(!vis[v])
{
DFS(v,len+tmpNode->len,cost+tmpNode->toll);
vis[v] = 0;
}
}
return 0;
}
int solve::processIn()
{
int s,d,l,t;
while(R--)
{
scanf("%d%d%d%d",&s,&d,&l,&t);
g->adjInsert(s,d,l,t);
}
return 0;
}
int main()
{
int k,n,r;
while(~scanf("%d%d%d",&k,&n,&r))
{
solve poj_1724(k,n,r);
}
return 0;
}
BFS:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
#define INF 0X7F7F7F7F
class node
{
public:
short adjx;
short len;
short toll;
node* next;
};
class adjList
{
public:
node** adj;
adjList(int n):adj(new node*[n])
{
memset(adj,0,sizeof(node*)*(n));
}
int adjInsert(int nodeNo,int adjx,int len,int toll)
{
node* newNode = new node;
newNode->adjx = adjx;
newNode->len = len;
newNode->toll = toll;
newNode->next = adj[nodeNo];
adj[nodeNo] = newNode;
return 0;
}
};
class solve
{
private:
int K,N,R;
adjList* g;
int minLen;
int totToll;
short** dp;
public:
solve(int k,int n,int r):K(k),N(n),R(r),minLen(INF),totToll(0)
{
g = new adjList(N+1);
processIn();
BFS();
printf("%d\n",minLen == INF?-1:minLen);
}
~solve()
{
delete[] g;
delete[] dp;
}
int processIn();
int BFS();
};
class queueNode
{
public:
int nodeNo;
short cost;
};
int solve::BFS()
{
int i;
queueNode now,next;
totToll = min(totToll,K);
dp = new short*[N+1];
for(i = 1;i <= N;i++)
{
dp[i] = new short[totToll+1];
memset(dp[i],0X7F,sizeof(short)*(totToll+1));
}
queue<queueNode> q;
now.nodeNo = 1;
now.cost = 0;
dp[1][0] = 0;
q.push(now);
while(!q.empty())
{
now = q.front();
q.pop();
if(dp[now.nodeNo][now.cost] >= minLen)
{
continue;
}
if(now.nodeNo == N)
{
if(minLen > dp[N][now.cost])
{
minLen = dp[N][now.cost];
}
continue;
}
for(node* tmpNode = g->adj[now.nodeNo];tmpNode != NULL;tmpNode = tmpNode->next)
{
next.nodeNo = tmpNode->adjx;
next.cost = tmpNode->toll+now.cost;
if(next.nodeNo != 1&&next.cost <= totToll&&dp[next.nodeNo][next.cost] > tmpNode->len+dp[now.nodeNo][now.cost])
{
q.push(next);
dp[next.nodeNo][next.cost] = tmpNode->len+dp[now.nodeNo][now.cost];
}
}
}
return 0;
}
int solve::processIn()
{
int s,d,l,t;
while(R--)
{
scanf("%d%d%d%d",&s,&d,&l,&t);
g->adjInsert(s,d,l,t);
totToll += t;
}
return 0;
}
int main()
{
int k,n,r;
while(~scanf("%d%d%d",&k,&n,&r))
{
solve poj_1724(k,n,r);
}
return 0;
}