7-9 超级玛丽
假定有n个城堡,编号为1至n,有的城堡之间有道路直接相连,有的城堡之间没有道路直接相连。马里奥现在准备从一个城堡出发前往另一个城堡,它有一个魔法棒,可以瞬时通过一条道路,即以0时间通过这条道路,但魔法棒最多只能用一次。马里奥想以最短的时间到达目的地,请编写程序为马里奥选定一条路线以及在什么地方使用魔法棒。假定所有道路为双向,保证从起点肯定能到达目的地。
输入格式:
输入第一行为4个整数n、s、t、m,分别表示城堡数(编号为1至n,n不超过10000),马里奥所在的起点s和想去的终点t,城堡间的道路数目。接下来m行,每行为3个正整数a、b、c,表示城堡a和城堡b之间有一条道路直接相连,通过该道路需要c分钟。
输出格式:
输出为空格间隔的2个整数,第1个整数为马里奥从起点到目的地所需的最短时间;第2个整数表示使用魔法棒的地点,即城堡编号,若有多个可能的地点,则输出编号最小者。
输入样例:
4 1 4 4
1 2 9
2 4 1
1 3 3
3 4 5
输出样例:
1 1
一直有个点错。。。不晓得哪错了,只有7分
代码:
#include <iostream>
using namespace std;
int n,s,t,m;
int a[20001][20001];
int vis[20001];
int tempnumber=1e8,tempmax=-111111,tempminn;///暂时
int remnumber=1e8,remminn=1e8;;///实际
void dfs(int x)
{
if(tempminn-tempmax>remminn)///剪枝
return;
if(x==t)
{
if(tempminn-tempmax<remminn)
{
remminn=tempminn-tempmax;
remnumber=tempnumber;
}
else if(tempminn-tempmax==remminn&&tempnumber<remnumber)
{
remminn=tempminn-tempmax;
remnumber=tempnumber;
}
return;
}
for(int i=1;i<=n;i++)
{
if(!vis[i]&&a[x][i])
{
int temp1=tempmax,temp2=tempnumber;
vis[i]=1;
if(a[x][i]>tempmax)
{
tempmax=a[x][i];
tempnumber=x;
}
else if(a[x][i]==tempmax)
{
tempmax=a[x][i];
tempnumber=min(tempnumber,x);
}
tempminn+=a[x][i];
dfs(i);
vis[i]=0;
tempmax=temp1;
tempnumber=temp2;
tempminn-=a[x][i];
}
}
}
int main()
{
cin>>n>>s>>t>>m;///分别表示城堡数,起点s,终点t,道路数目
int q,b,c;
for(int i=0;i<m;i++)
{
cin>>q>>b>>c;
a[q][b]=a[b][q]=c;
}
vis[s]=1;
dfs(s);
cout<<remminn<<' '<<remnumber;
return 0;
}
202206201626一