#include<bits/stdc++.h>//深搜没水过-超时(思路没错的话)
using namespace std;
const int N=55;
int a[N][N];
int cost[N];
int ans;
int book[N][N],ff[N];
int n,to,maxn;
int temp[N][N];
void dfs(int from,int s)
{
if(s-maxn>=ans) return;
if(from==to)
{
if(s-cost[to]<ans)
{
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
temp[i][j]=book[i][j];
ans=s-cost[to];
}
return;
}
for(int i=1;i<=n;i++)
{
if(!book[from][i]&&a[from][i]>0)
{
book[i][from]=1;
book[from][i]=1;
dfs(i,s+a[from][i]);
book[from][i]=0;
book[i][from]=1;
}
}
}
int main()
{
while(scanf("%d",&n))
{
if(n==0) break;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
scanf("%d",&a[i][j]);
}
}
for(int i=1;i<=n;i++) scanf("%d",&cost[i]);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(a[i][j]==0) a[i][j]=-1;
if(a[i][j]!=-1) a[i][j]+=cost[j];
}
}
maxn=-1;
for(int i=1;i<=n;i++)
{
if(cost[i]>maxn) maxn=cost[i];
}
int x,y;
while(scanf("%d%d",&x,&y))
{
if(x==-1&&y==-1) break;
ans=9999999;to=y;
dfs(x,0);
int num=0;
ff[num++]=x;
int x1=x,y1=y;
while(1)
{
int flag=1;
for(int i=1;i<=n;i++)
{
if(temp[x][i]){flag=0;temp[x][i]=0;ff[num++]=i;x=i;}
}
if(flag) break;
}
printf("From %d to %d :\nPath: \n",x1,y1);
for(int i=0;i<num-1;i++)
{
printf("%d-->",ff[i]);
}printf("%d\n",ff[num-1]);
printf("Total cost : %d\n\n",ans);
}
}
return 0;
}
#include<bits/stdc++.h>//floyd 打印路径
#define inf 999999
using namespace std;
const int N=100;
int a[N][N];
int cost[N];
int _next[N][N];
int c[N][N];
int ff[N];
int main()
{
int n;
while(scanf("%d",&n))
{
if(n==0) break;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
scanf("%d",&c[i][j]);
for(int i=1;i<=n;i++) scanf("%d",&cost[i]);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(c[i][j]==-1) c[i][j]=inf;
_next[i][j]=j;
}
}
for(int k=1;k<=n;k++)
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
if(c[i][k]+c[k][j]+cost[k]<c[i][j])
{
c[i][j]=c[i][k]+c[k][j]+cost[k];
_next[i][j]=_next[i][k];
}
else if(c[i][k]+c[k][j]+cost[k]==c[i][j]&&_next[i][k]<_next[i][j])
{
_next[i][j]=_next[i][k];
}
}
int x,y;
while(scanf("%d%d",&x,&y))
{
if(x==-1&&y==-1) break;
printf("From %d to %d :\nPath: ",x,y);
int num=0;
for(int i=x;i!=y;i=_next[i][y])
{
ff[num++]=i;
}ff[num++]=y;
for(int i=0;i<num-1;i++)
printf("%d-->",ff[i]);
printf("%d\n",ff[num-1]);
printf("Total cost : %d\n\n",c[x][y]);
}
}
return 0;
}
#include<bits/stdc++.h>//贴下第一遍的代码。。蒙着头来了便广搜,才直觉要标记完整路径才行,而不是这个写的标记两点间的来回趟。深搜才能处理这问题,但路径
using namespace std; //深搜才能处理这问题,,写时神奇的用二维坐标储存路径,再在头节点从二维标记中拉出路径。深搜传数组就能保存路径呀。。不补了。
const int N=1010;
int a[N][N];
int cost[N];
int ans,pos;
struct node
{
int p,pre,value;
}c[N*N];
int book[N][N],ff[N];
//void bfs(int from,int to,int n)
//{
// memset(book,0,sizeof(book));
// int head=0,tail=1;
// c[head].p=from;c[head].pre=-1,c[head].value=0;
// while(head<tail)
// {
// int gg=c[head].p;
// for(int i=1;i<=n;i++)
// {
// if(a[gg][i]>0&&!book[gg][i])
// {
// book[gg][i]=1;
// c[tail].p=i,c[tail].pre=head;c[tail].value=c[head].value+a[gg][i];
// if(i==to){c[tail].value-=cost[i];}
// if(i==to&&c[tail].value<ans)
// {
// ans=c[tail].value;
// pos=tail;
// }
// tail++;
// }
// }
// head++;
// }
// //for(int i=0;i<tail;i++) printf("%d %d %d\n",c[i].pre,c[i].p,c[i].value);
//}
int n,to;
int temp[N][N];
void dfs(int from,int s)
{
if(from==to&&s-cost[to]<ans)
{
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
temp[i][j]=book[i][j];
ans=s-cost[to];return;
}
for(int i=1;i<=n;i++)
{
if(!book[from][i]&&a[from][i]>0)
{
book[from][i]=1;dfs(i,s+a[from][i]);book[from][i]=0;
}
}
}
int main()
{
while(scanf("%d",&n))
{
if(n==0) break;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
scanf("%d",&a[i][j]);
}
}
for(int i=1;i<=n;i++) scanf("%d",&cost[i]);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(a[i][j]==0) a[i][j]=-1;
if(a[i][j]!=-1) a[i][j]+=cost[j];
}
}
int x,y;
while(scanf("%d%d",&x,&y))
{
if(x==-1&&y==-1) break;
// ans=9999999;pos=-1; bfs(x,y,n);
// int num=0;
// ff[num++]=y;
// //printf("pos=%d\n",pos);
// for(int i=c[pos].pre;i!=-1;i=c[i].pre)
// {
// ff[num++]=c[i].p;
// }
// printf("From %d to %d :\nPath: \n",x,y);
// for(int i=num-1;i>0;i--)
// {
// printf("%d-->",ff[i]);
// }printf("%d\n",ff[0]);
// printf("Total cost : %d\n",c[pos].value);
ans=9999999;to=y;
dfs(x,0);
int num=0;
ff[num++]=x;
// for(int i=1;i<=n;i++)
// {
// for(int j=1;j<=n;j++)
// printf("%d ",temp[i][j]);printf("\n");
// }
int x1=x,y1=y;
while(1)
{
int flag=1;
for(int i=1;i<=n;i++)
{
if(temp[x][i]){flag=0;temp[x][i]=0;ff[num++]=i;x=i;}
}
if(flag) break;
}
printf("From %d to %d :\nPath: \n",x1,y1);
for(int i=0;i<num-1;i++)
{
printf("%d-->",ff[i]);
}printf("%d\n",ff[num-1]);
printf("Total cost : %d\n\n",ans);
}
}
return 0;
}
Minimum Transport Cost