zoj 3370(二分+二分图染色)

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=3912

思路:二分覆盖直径,然后判断是否有冲突(即距离小于等于直径的不能使用同一频率),这样可以用二分图染色的办法判断,看是否能将整个图都染上色。

 1 #include<iostream>

 2 #include<cstdio>

 3 #include<cstring>

 4 #include<algorithm>

 5 #include<queue>

 6 #include<cmath>

 7 using namespace std;

 8 #define MAXN 1444

 9 #define inf 1<<30

10 #define eps 1e-9

11 

12 struct Point{

13     double x,y;

14 }p[MAXN];

15 

16 double map[MAXN][MAXN];

17 int color[MAXN];

18 int ans[MAXN];

19 int n;

20 

21 double Get_Dist(int i,int j)

22 {

23     double d1=(p[i].x-p[j].x)*(p[i].x-p[j].x);

24     double d2=(p[i].y-p[j].y)*(p[i].y-p[j].y);

25     return sqrt(d1+d2);

26 }

27 

28 bool Judge(double limit)

29 {

30     memset(color,0,sizeof(color));

31     queue<int>que;

32     for(int i=1;i<=n;i++){

33         if(color[i]==0){

34             color[i]=1;

35             que.push(i);

36             while(!que.empty()){

37                 int u=que.front();

38                 que.pop();

39                 for(int v=1;v<=n;v++){

40                     if(map[u][v]>limit-eps)continue;

41                     if(color[u]==color[v])return false;

42                     if(color[v]==0){

43                         color[v]=3-color[u];

44                         que.push(v);

45                     }

46                 }

47             }

48         }

49     }

50     for(int i=1;i<=n;i++)ans[i]=color[i];

51     return true;

52 }

53 

54     

55 

56 int main()

57 {

58     while(~scanf("%d",&n)){

59         for(int i=1;i<=n;i++)scanf("%lf%lf",&p[i].x,&p[i].y);

60         for(int i=1;i<=n;i++)

61             for(int j=1;j<=n;j++)

62                 map[i][j]=(i==j?inf:Get_Dist(i,j));

63         double low=0,high=40000.0,mid;

64         while(high-low>eps){

65             mid=(low+high)/2;

66             if(Judge(mid)){

67                 low=mid;

68             }else

69                 high=mid;

70         }

71         printf("%.10f\n",mid/2);

72         for(int i=1;i<=n;i++){

73             printf(i==n?"%d\n":"%d ",ans[i]);

74         }

75     }

76     return 0;

77 }
View Code

 

你可能感兴趣的:(二分图)