题意:构造图过程中,若IP和子网掩码的按位与有相同,则连通无权,求出既定两点的路径。
思路:先构图,用dijkstra求最短路,输出路径。
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <algorithm>
#include <math.h>
using namespace std;
const int MAX = 100;
long long ip[MAX][6];
int map[MAX][MAX];
int len[MAX];
int a[MAX],n;
bool check(int x,int y){
for(int i=0;i<a[x];i++)
for(int k=0;k<a[y];k++)
if(ip[x][i]==ip[y][k])
return true;
return false;
}
int pre[MAX];
void output(int t){
if(pre[t]==-1) return;
output(pre[t]);
printf(" %d",t);
}
void Dijkstra(int s,int t){
bool used[MAX];
int dis[MAX];
memset(used,false,sizeof(used));
fill(dis,dis+MAX,INT_MAX);
memset(pre,-1,sizeof(pre));
dis[s]=0;
used[s]=true;
int now=s;
for(int i=0;i<n;i++){
for(int k=1;k<=n;k++)
if(map[now][k]&&dis[k]>dis[now]+1){
dis[k]=dis[now]+1;
pre[k]=now;
}
int mi=INT_MAX;
for(int k=1;k<=n;k++)
if(!used[k]&&dis[k]<mi)
mi=dis[now=k];
used[now]=1;
}
if(dis[t]==INT_MAX ){
printf("No\n");
return;
}
printf("Yes\n");
printf("%d",s);
output(t);
printf("\n");
}
int main(){
int t1[5],t2[5],s,t;
scanf("%d",&n);
memset(len,0,sizeof(len));
memset(ip,0,sizeof(ip));
memset(map,0,sizeof(map));
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
for(int k=0;k<a[i];k++){
scanf("%d.%d.%d.%d",&t1[0],&t1[1],&t1[2],&t1[3]);
scanf("%d.%d.%d.%d",&t2[0],&t2[1],&t2[2],&t2[3]);
for(int p=0;p<4;p++){
ip[i][k]*=1000;
ip[i][k]+=(t1[p]&t2[p]);
}
}
for(int k=1;k<i;k++)
if(check(k,i))
map[i][k]=map[k][i]=1;
}
scanf("%d %d",&s,&t);
Dijkstra(s,t);
return 0;
}
/*测试:
Sample Input
6
2
10.0.0.1 255.0.0.0
192.168.0.1 255.255.255.0
1
10.0.0.2 255.0.0.0
3
192.168.0.2 255.255.255.0
212.220.31.1 255.255.255.0
212.220.35.1 255.255.255.0
1
212.220.31.2 255.255.255.0
2
212.220.35.2 255.255.255.0
195.38.54.65 255.255.255.224
1
195.38.54.94 255.255.255.224
1 6
Sample Output
Yes
1 3 5 6
*/