版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Nightmare_ak/article/details/84886776
嘤嘤嘤,有点难打啊- =,暴力跑最短路,Dijsktra应该不行,因为先出队列的不一定最优。
#include<cstdio>
#include<cstring>
#include<vector>
#include<map>
using namespace std;
typedef long long ll;
const int N=10000;
const int INF=0x3f3f3f3f;
struct Edge
{
int v,w,next;
}edge[N*N];
int st,ed,vis[N],head[N],edgetot,mincost,mindis,cnt;
vector<int> res,now;
map<int,int> mp,rmp;
map<ll,int> color;
void dfs(int u,int dis,int cost,int pre)
{
vis[u]=1,now.push_back(u);
if(u==ed)
{
if(dis<mindis||dis==mindis&&cost<mincost)
mindis=dis,mincost=cost,res=now;
vis[u]=0,now.pop_back();
return;
}
for(int i=head[u];i!=-1;i=edge[i].next)
{
int v=edge[i].v,w=(edge[i].w!=pre);
if(vis[v]) continue;
dfs(v,dis+1,cost+w,edge[i].w);
}
vis[u]=0,now.pop_back();
}
void addEdge(int u,int v,int w)
{
edge[edgetot]={v,w,head[u]};
head[u]=edgetot++;
}
int main()
{
edgetot=0,cnt=0;
memset(head,-1,sizeof(head));
int n;scanf("%d",&n);
for(int i=1;i<=n;i++)
{
int k;scanf("%d",&k);
int u;
for(int j=1;j<=k;j++)
{
int v;scanf("%d",&v);
if(!mp.count(v)) mp[v]=++cnt,rmp[cnt]=v;
v=mp[v];
if(j!=1)
{
addEdge(u,v,i),addEdge(v,u,i);
color[u*N+v]=color[v*N+u]=i;
}
u=v;
}
}
int q;scanf("%d",&q);
while(q--)
{
scanf("%d%d",&st,&ed);
st=mp[st],ed=mp[ed];
mincost=mindis=INF;
dfs(st,0,0,0);
printf("%d\n",mindis);
int pre=color[res[0]*N+res[1]],pnode=res[0];
for(int i=1;i<res.size();i++)
{
if(color[res[i-1]*N+res[i]]!=pre)
{
printf("Take Line#%d from %04d to %04d.\n",pre,rmp[pnode],rmp[res[i-1]]);
pre=color[res[i-1]*N+res[i]],pnode=res[i-1];
}
}
printf("Take Line#%d from %04d to %04d.\n",pre,rmp[pnode],rmp[ed]);
}
return 0;
}