http://www.vijos.cn/Problem_Show.asp?id=1399
背景 Background
怪盗基德第四次拿着战利品信心满满地离开了OIBH总部,一路上大摇大摆,好不嚣张。OIBH的人看不下去又没办法,打算作罢,可是有一天……当当当当……当OIBH总部的吃饭铃声响起的时候,所有正在埋头工作的大牛们都以迅雷不及掩耳盗铃之势向食堂冲去。食堂的大门顿时被人群塞的鼓鼓的(可怜ing...)当大牛们正在全力消灭由水稻演变而来的那东西时,突然走进来一个玉树临风英俊潇洒人见人爱花见花开啤酒见啤酒盖开的大帅哥(啊啊啊啊啊啊啊啊啊啊……),而他自称是一个超超超级大牛!!超超超级大牛在听说了怪盗基德的事情后,二话不说,提笔“刷刷”的写了一页纸,其余大牛们研究了九天九夜,终于明白了纸上写的是什么,那是一个(咳咳)专门对付怪盗基德的陷阱!而怪盗基德在毫不知情的情况下,竟然把四块宝石都送回了OIBH总部,还留下预告函,将向第五块宝石发起攻势!大牛们气愤而又坏笑着,悄悄地设下了陷阱……结果出乎所有人的意料,宝石还是被拿走了,可是,为什么大牛们还在阴笑……难不成,他们在怪盗基德逃离的路上设下了陷阱?
描述 Description
果然,基德的撤退路上被布置一个巨大的迷宫。这迷宫是一个巨大的道路网,每条路上基德需要花费的时间都不同,而每条路都需要不同的过路费。这个道路网可以看做一个无向图,其中共有n个结点,共m对结点间有通路。1号结点是入口,n号结点是出口。现在要求你在规定时间内,花去尽可能多的钱(据说不这样做就不是基德的性格)帮助基德走过迷宫。注意:每条路只能走一次,走到终点即结束而不能往回走。在钱数相同的情况下使时间尽量短。
输入格式 Input Format
第一行4个整数n,m,t,v,分别是结点总数,通路总数,规定时间,及基德所拥有的钱。接下去m行,每行4个整数a,b,c,d,a和b表示有通路的两结点,c为此路费时,d代表此路过路费。
输出格式 Output Format
输出共2个整数t2,v2,分别表示用时和所剩钱数。你要保证t2<=t且v2>=0。
样例输入 Sample Input
8 10 10 120
1 2 2 1
1 3 1 1
1 4 2 19
2 3 2 6
3 4 1 1
3 5 2 2
5 6 2 1
6 7 1 3
7 8 3 1
4 8 7 100
样例输出 Sample Output
9 1
时间限制 Time Limitation
每个点1s
注释 Hint
2<=n<=100 1<=t,v<=500
样例说明
道路网如图所示【道路上括号外为费时,括号内为过路费】
1->4->8即为所求路径,用时为9,费钱为119。
分析:
DFS搜索题,题目规定每条边只可行走一次,并且图是双向的。
开个vis数组: vis[i][j]表示(i,j)是否走过。
开个g数组: g[i][j]表示(i,j)有边连接。
最后DFS,没当到达n是则询问产生的的结果是否比当前的更优(注意题目给出的比较方式)
【参考程序】:
#include<cstring>
#include<cstdio>
#include<iostream>
using namespace std;
bool vis[110][110],g[110][110];
int cost[110][110],times[110][110];
int n,m,t,v,ansc,anst;
void dfs(int now,int ts,int cs)
{
if (now==n)
{
if (cs<ansc && cs>=0 && ts<=t)
{
ansc=cs; anst=ts;
}
else if (cs==ansc && ts<anst) anst=ts;
return ;
}
for (int i=1;i<=n;i++)
if (!vis[now][i] && g[now][i])
{
vis[now][i]=vis[i][now]=true;
dfs(i,ts+times[now][i],cs-cost[now][i]);
vis[now][i]=vis[i][now]=false;
}
}
int main()
{
scanf("%d%d%d%d",&n,&m,&t,&v);
memset(vis,false,sizeof(vis));
memset(g,false,sizeof(g));
int a,b,c,d;
for (int i=1;i<=m;i++)
{
scanf("%d%d%d%d",&a,&b,&c,&d);
g[a][b]=g[b][a]=true;
cost[a][b]=cost[b][a]=d;
times[a][b]=times[b][a]=c;
}
ansc=anst=0xFFFFFFF;
dfs(1,0,v);
printf("%d %d\n",anst,ansc);
return 0;
}