Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 1211 Accepted Submission(s): 304
本题并不是很难,关键是路径的选择,如果有正确的选择路径方法,对大家来说应该都不是太难。本题思想 最短路
代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<stdio.h>
#include<queue>
#include<stack>
using namespace std;
int com(const void *a,const void *b)
{
return *(int *)a-*(int *)b;
};
typedef struct node
{
int s,data;
bool operator<(const node &a)const
{
if(a.s==s)
return a.data<data;
return a.s<s;
}
}NODE;
NODE cur,next;
int pre[1000],dist[1000],start,end,n,a[1000][1000],b[1000];
stack<int >st;
int test(int x,int y)
{
if(pre[x]==pre[y] && x<y)
return 1;
if(pre[x]==pre[y])
return 0;
if(pre[x]==start)
{
if(test(x,pre[y]))
return 1;
}
else if(pre[y]==start)
{
if(test(pre[x],y))
return 1;
}
else
{
if(test(x,pre[y]))
return 1;
if(test(pre[x],y))
return 1;
if(test(pre[x],pre[y]))
return 1;
}
return 0;
}
void dijkstra(int v0)
{
priority_queue<NODE> qu;
cur.data=v0;
cur.s=0;
int visit[1000],mark=0,i;
memset(visit,0,sizeof(visit));
memset(dist,-1,sizeof(dist));
qu.push (cur);
dist[v0]=0;
while(!qu.empty ())
{
cur=qu.top ();
while(visit[cur.data])
{
qu.pop();
if(qu.empty ())
{
mark=1;
break;
}
cur=qu.top();
}
if(mark)
break;
qu.pop();
if(cur.data==end)
return ;
visit[cur.data]=1;
for(i=1;i<=n;i++)
{
if(!visit[i] && a[cur.data][i]!=-1 )
{
if(i==end)
{
if(dist[i]==-1 || dist[cur.data]+a[cur.data][i]<=dist[i])
{
if(dist[i]!=-1 && dist[cur.data]+a[cur.data][i]==dist[i])
{
if(test(cur.data,i))
pre[i]=cur.data;
}
else
{
pre[i]=cur.data;
}
next.data=i;
dist[i]=next.s=a[cur.data][i]+dist[cur.data];
qu.push(next);
}
}
else
{
if(dist[i]==-1 || dist[cur.data]+a[cur.data][i]+b[i]<=dist[i])
{
if(dist[i]!=-1 && dist[cur.data]+a[cur.data][i]+b[i]==dist[i])
{
if(test(cur.data,i))
pre[i]=cur.data;
}
else
{
pre[i]=cur.data;
}
next.data=i;
dist[i]=next.s=a[cur.data][i]+dist[cur.data]+b[i];
qu.push(next);
}
}
}
}
}
}
void re(int x)
{
if(x==start)
return ;
st.push(x);
re(pre[x]);
}
int main()
{
// freopen("q1456.in","r",stdin);
// freopen("3.out","w",stdout);
int i,j;
while(scanf("%d",&n)!=EOF)
{
if(n==0)
break;
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
scanf("%d",&a[i][j]);
for(i=1;i<=n;i++)
scanf("%d",&b[i]);
while(1)
{
scanf("%d%d",&start,&end);
if(start==-1 && end==-1)
break;
dijkstra(start);
printf("From %d to %d :\n",start,end);
re(end);
printf("Path: %d",start);
while(!st.empty ())
{
printf("-->%d",st.top ());
st.pop();
}
printf("\nTotal cost : %d\n",dist[end]);
printf("\n");
}
}
return 0;
}