Question: N cities are given. We need to traverse all vertices from 1 and select some vertices to build a gas station to minimize the cost.
Http://acm.hdu.edu.cn/showproblem.php? Pid = 1, 4435
The special nature of this question lies in his spending, 2 ^ (I-1)
Using a very important property, 2 ^ 0 + 2 ^ 1 + 2 ^ 2 ...... + 2 ^ I <2 ^ (I + 1)
All vertices with no. <= I are created, and the total cost is less than that of creating one vertex.
Here we are greedy. Let's assume that all vertices are created, and then delete vertices with large numbers in sequence to see if we can traverse the entire graph.
Dist [I] indicates the distance between the vertex I and the nearest gas station.
[Cpp]
# Include <iostream>
# Include <cstdio>
# Include <map>
# Include <cstring>
# Include <cmath>
# Include <vector>
# Include <algorithm>
# Include <set>
# Include <string>
# Include <queue>
# Define inf 1 <30
# Define M 2005
# Define N 130
# Define maxn300005
# Define eps 1e-10
# Define zero (a) fabs (a) <eps
# Define Min (a, B) (a) <(B )? (A) (B ))
# Define Max (a, B) (a)> (B )? (A) (B ))
# Define pb (a) push_back ()
# Define mp (a, B) make_pair (a, B)
# Define mem (a, B) memset (a, B, sizeof ())
# Define LL long
# Define lson step <1
# Define rson step <1 | 1
# Define MOD 1000000009.
# Define sqr (a) * ())
# Define Key_value ch [ch [root] [1] [0]
# Pragma comment (linker, "/STACK: 1024000000,1024000000 ")
Using namespace std;
Struct Point
{
Int x, y;
} P [N];
Int n, d;
Int path [N] [N];
Int OK [N];
Double dist (int I, int j)
{
Return sqrt (double) sqr (p [I]. x-p [j]. x) + sqr (p [I]. y-p [j]. y ));
}
Bool bfs ()
{
Bool vis [N];
Int dist [N];
Queue <int> que;
Mem (vis, false );
For (int I = 0; I <n; I ++)
{
// It is a gas station and the distance is 0
If (OK [I]) dist [I] = 0;
Else dist [I] = inf;
}
Que. push (0); vis [0] = true;
While (! Que. empty ())
{
Int u = que. front ();
Que. pop ();
For (int I = 0; I <n; I ++)
{
If (! Vis [I] & path [u] [I] <= d)
{
Dist [I] = min (dist [I], dist [u] + path [u] [I]);
If (OK [I])
{
Que. push (I );
Vis [I] = true;
}
}
}
}
For (int I = 0; I <n; I ++)
{
// Although it is a gas station, it cannot start from 1.
If (OK [I] &! Vis [I]) return false;
// Unlike a gas station, it cannot be guaranteed to return from a gas station
If (! OK [I] & dist [I] * 2> d) return false;
}
Return true;
}
Void slove ()
{
For (int I = 0; I <n; I ++) OK [I] = 1;
If (! Bfs () {puts ("-1"); return ;}// all are created and cannot be traversed
For (int I = n-1; I> 0; I --)
{
OK [I] = 0;
If (! Bfs () OK [I] = 1;
}
Int j = n-1;
While (! OK [j]) j --;
For (int I = j; I> = 0; I --) printf ("% d", OK [I]);
Puts ("");
}
Int main ()
{
While (scanf ("% d", & n, & d )! = EOF)
{
For (int I = 0; I <n; I ++) scanf ("% d", & p [I]. x, & p [I]. y );
For (int I = 0; I <n; I ++)
{
For (int j = 0; j <n; j ++)
{
Path [I] [j] = ceil (dist (I, j ));
}
}
Slove ();
}
Return 0;
}
# Include <iostream>
# Include <cstdio>
# Include <map>
# Include <cstring>
# Include <cmath>
# Include <vector>
# Include <algorithm>
# Include <set>
# Include <string>
# Include <queue>
# Define inf 1 <30
# Define M 2005
# Define N 130
# Define maxn300005
# Define eps 1e-10
# Define zero (a) fabs (a) <eps
# Define Min (a, B) (a) <(B )? (A) (B ))
# Define Max (a, B) (a)> (B )? (A) (B ))
# Define pb (a) push_back ()
# Define mp (a, B) make_pair (a, B)
# Define mem (a, B) memset (a, B, sizeof ())
# Define LL long
# Define lson step <1
# Define rson step <1 | 1
# Define MOD 1000000009.
# Define sqr (a) * ())
# Define Key_value ch [ch [root] [1] [0]
# Pragma comment (linker, "/STACK: 1024000000,1024000000 ")
Using namespace std;
Struct Point
{
Int x, y;
} P [N];
Int n, d;
Int path [N] [N];
Int OK [N];
Double dist (int I, int j)
{
Return sqrt (double) sqr (p [I]. x-p [j]. x) + sqr (p [I]. y-p [j]. y ));
}
Bool bfs ()
{
Bool vis [N];
Int dist [N];
Queue <int> que;
Mem (vis, false );
For (int I = 0; I <n; I ++)
{
// It is a gas station and the distance is 0
If (OK [I]) dist [I] = 0;
Else dist [I] = inf;
}
Que. push (0); vis [0] = true;
While (! Que. empty ())
{
Int u = que. front ();
Que. pop ();
For (int I = 0; I <n; I ++)
{
If (! Vis [I] & path [u] [I] <= d)
{
Dist [I] = min (dist [I], dist [u] + path [u] [I]);
If (OK [I])
{
Que. push (I );
Vis [I] = true;
}
}
}
}
For (int I = 0; I <n; I ++)
{
// Although it is a gas station, it cannot start from 1.
If (OK [I] &! Vis [I]) return false;
// Unlike a gas station, it cannot be guaranteed to return from a gas station
If (! OK [I] & dist [I] * 2> d) return false;
}
Return true;
}
Void slove ()
{
For (int I = 0; I <n; I ++) OK [I] = 1;
If (! Bfs () {puts ("-1"); return ;}// all are created and cannot be traversed
For (int I = n-1; I> 0; I --)
{
OK [I] = 0;
If (! Bfs () OK [I] = 1;
}
Int j = n-1;
While (! OK [j]) j --;
For (int I = j; I> = 0; I --) printf ("% d", OK [I]);
Puts ("");
}
Int main ()
{
While (scanf ("% d", & n, & d )! = EOF)
{
For (int I = 0; I <n; I ++) scanf ("% d", & p [I]. x, & p [I]. y );
For (int I = 0; I <n; I ++)
{
For (int j = 0; j <n; j ++)
{
Path [I] [j] = ceil (dist (I, j ));
}
}
Slove ();
}
Return 0;
}