1072. Routing
Time limit: 1.0 second
Memory limit: 64 MB
There is a TCP/IP net of several computers. It means that:
- Each computer has one or more net interfaces.
- Each interface is identified by its IP-address and a subnet mask — these are two four-byte numbers with a point after each byte. A subnet mask has a binary representation as follows: there are k 1-bits, then — m 0-bits, k+m=8*4=32 (e.g., 212.220.35.77 — is an IP-address and 255.255.255.128 — is a subnet mask).
- Two computers belong to the same subnet, if and only if (IP1 AND NetMask1) = (IP2 AND NetMask2), where IPi and NetMaski — are an IP-address and subnet mask of i-th computer, AND — is bitwise.
- A packet is transmitted between two computers of one subnet directly.
- If two computers belong to different subnets, a packet is to be transmitted via some other computers. The packet can pass from one subnet to another only on computer that has both subnets interfaces.
Your task is to find the shortest way of a packet between two given computers.
Input
The first line contains a number N — an amount of computers in the net, then go N sections, describing interfaces of each computer. There is a number K in the first line of a section — that is an amount of interfaces of the computer, then go K lines — descriptions of the interfaces, i.e. its IP-address and a subnet mask. The last line of an input contains two integers — the numbers of the computers that you are to find a way between them.
You may assume that 2 ≤ N ≤ 90 and K ≤ 5.
Output
The word “Yes” if the route exists, then in the next line the computer numbers passed by the packet, separated with a space. The word “No” otherwise.
Sample
input | output |
---|---|
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 |
Yes 1 3 5 6 |
Problem Author: Evgeny Kobzev
Problem Source: Ural State Univerisity Personal Contest Online February‘2001 Students Session
Tags: graph theory (hide tags for unsolved problems)
Difficulty: 464
题意:给出n台计算机,每台计算机有若干对IP地址以及子网掩码,当且仅当存在(IP地址i AND 子网掩码i) = (IP地址j AND 子网掩码j)时,两台计算机才可以联系。
问从一台计算机到另一台计算机最短要经过多少计算机。
输出方案。
分析:实际上就是最短路。
1 /** 2 Create By yzx - stupidboy 3 */ 4 #include <cstdio> 5 #include <cstring> 6 #include <cstdlib> 7 #include <cmath> 8 #include <deque> 9 #include <vector> 10 #include <queue> 11 #include <iostream> 12 #include <algorithm> 13 #include <map> 14 #include <set> 15 #include <ctime> 16 #include <iomanip> 17 using namespace std; 18 typedef long long LL; 19 typedef double DB; 20 #define MIT (2147483647) 21 #define INF (1000000001) 22 #define MLL (1000000000000000001LL) 23 #define sz(x) ((int) (x).size()) 24 #define clr(x, y) memset(x, y, sizeof(x)) 25 #define puf push_front 26 #define pub push_back 27 #define pof pop_front 28 #define pob pop_back 29 #define ft first 30 #define sd second 31 #define mk make_pair 32 33 inline int Getint() 34 { 35 int Ret = 0; 36 char Ch = ‘ ‘; 37 bool Flag = 0; 38 while(!(Ch >= ‘0‘ && Ch <= ‘9‘)) 39 { 40 if(Ch == ‘-‘) Flag ^= 1; 41 Ch = getchar(); 42 } 43 while(Ch >= ‘0‘ && Ch <= ‘9‘) 44 { 45 Ret = Ret * 10 + Ch - ‘0‘; 46 Ch = getchar(); 47 } 48 return Flag ? -Ret : Ret; 49 } 50 51 const int N = 110; 52 int n; 53 int length[N]; 54 vector<unsigned int> feature[N]; 55 bool graph[N][N]; 56 queue<int> que; 57 int dp[N], from[N], st, ed; 58 59 inline unsigned int Get() 60 { 61 const static unsigned int fact[4] = {16777216, 65536, 256, 1}; 62 unsigned int ret = 0; 63 for(int i = 0; i < 4; i++) 64 { 65 int x = (unsigned int) Getint(); 66 ret += x * fact[i]; 67 } 68 return ret; 69 } 70 71 inline void Input() 72 { 73 scanf("%d", &n); 74 for(int i = 1; i <= n; i++) 75 { 76 scanf("%d", &length[i]); 77 //cout << i << ": "; 78 for(int j = 1; j <= length[i]; j++) 79 { 80 unsigned int x, y; 81 x = Get(); 82 y = Get(); 83 feature[i].pub(x & y); 84 //cout << (x & y) << ‘ ‘; 85 } 86 //cout << endl; 87 } 88 scanf("%d%d", &st, &ed); 89 } 90 91 inline bool find(int x, int y) 92 { 93 int len1 = sz(feature[x]), len2 = sz(feature[y]); 94 for(int i = 0; i < len1; i++) 95 for(int j = 0; j < len2; j++) 96 if(feature[x][i] == feature[y][j]) 97 return 1; 98 return 0; 99 } 100 101 inline void Solve() 102 { 103 for(int i = 1; i <= n; i++) 104 for(int j = 1; j <= n; j++) 105 if(i != j && find(i, j)) 106 graph[i][j] = 1; 107 108 for(int i = 1; i <= n; i++) 109 from[i] = 0, dp[i] = INF; 110 dp[st] = 0; 111 que.push(st); 112 while(sz(que)) 113 { 114 int u = que.front(); 115 que.pop(); 116 for(int i = 1; i <= n; i++) 117 if(graph[u][i] && dp[i] > dp[u] + 1) 118 { 119 dp[i] = dp[u] + 1; 120 from[i] = u; 121 que.push(i); 122 } 123 } 124 125 if(dp[ed] == INF) printf("No\n"); 126 else 127 { 128 printf("Yes\n"); 129 vector<int> ans; 130 for(int x = ed; x; x = from[x]) ans.pub(x); 131 int length = sz(ans); 132 for(int i = length - 1; i >= 1; i--) 133 printf("%d ", ans[i]); 134 printf("%d\n", ans[0]); 135 } 136 } 137 138 int main() 139 { 140 freopen("d.in", "r", stdin); 141 Input(); 142 Solve(); 143 return 0; 144 }