• 分考场


    原创


    问题描述
      n个人参加某项特殊考试。
      为了公平,要求任何两个认识的人不能分在同一个考场。
      求是少需要分几个考场才能满足条件。
    输入格式
      第一行,一个整数n(1<n<100),表示参加考试的人数。
      第二行,一个整数m,表示接下来有m行数据
      以下m行每行的格式为:两个整数a,b,用空格分开 (1<=a,b<=n) 表示第a个人与第b个人认识。
    输出格式
      一行一个整数,表示最少分几个考场。
    样例输入
    5
    8
    1 2
    1 3
    1 4
    2 3
    2 4
    2 5
    3 4
    4 5
    样例输出
    4
    样例输入
    5
    10
    1 2
    1 3
    1 4
    1 5
    2 3
    2 4
    2 5
    3 4
    3 5
    4 5
    样例输出
    5
    一个无向图着色,要求相邻的点不能是同色,方案有多种,找出所用颜色数最少的方案即可解题。
      着色过程是按点顺序一一着色,n个点,一一按顺序为点1~n着色,着色完一个点继续着色下一个点,直至着色完n个点。
      由于一个点可以多种合理的着色方案,不同的着色方案对最终的颜色种数影响是不同的,所以需要一一比较所有的方案,过程类似
    深搜回溯。
     1 import java.util.*;
     2 
     3 public class Main {
     4     
     5     static int n;    //考试人数
     6     static int m;    //m个关系
     7     static int matrix[][];    //邻接矩阵
     8     static int max=0;    //用了的颜色数
     9     static int pid_Color[];    //存储点用了哪种颜色
    10     static int flag=0;
    11     static int res=99999;
    12     
    13     static boolean judge(int pid,int color) {
    14         for(int i=1;i<=n;i++) {
    15             //邻接点判断
    16             if(matrix[pid][i]==1) {
    17                 //判断邻接点是否涂色
    18                 if(pid_Color[i]!=0) {
    19                     //邻接点颜色判断
    20                     if(pid_Color[i]==color) {
    21                         return false;
    22                     }
    23                 }
    24             }
    25         }
    26         return true;
    27     }
    28     
    29     static void color_Painting(int pid,int color_Num) {    //pid代表点,目前已经用了color_Num种颜色
    30         if(color_Num>=res) {
    31             return;
    32         }
    33         if(pid>n) {
    34             res=res<color_Num?res:color_Num;
    35             return;
    36         }
    37         //枚举颜色1~color_Num,看看可不可以用在点pid
    38         for(int color=1;color<=color_Num;color++) {
    39             //可以
    40             if( judge(pid,color)==true ) {
    41                 pid_Color[pid]=color;    //涂色
    42                 color_Painting(pid+1,color_Num);//涂下一个点
    43                 pid_Color[pid]=0;
    44             }
    45         }
    46         //颜色1~color_Num都用不了,用新的颜色
    47         pid_Color[pid]=color_Num+1;
    48         color_Painting(pid+1,color_Num+1);
    49         pid_Color[pid]=0;
    50     }
    51 
    52     public static void main(String[] args) {
    53         Scanner reader=new Scanner(System.in);
    54         n=reader.nextInt();
    55         m=reader.nextInt();
    56         matrix=new int[n+1][n+1];    //编号从1开始
    57         pid_Color=new int[n+1];
    58         //读入m个关系
    59         for(int i=1;i<=m;i++) {
    60             int a=reader.nextInt();
    61             int b=reader.nextInt();
    62             //无向图
    63             matrix[a][b]=1;
    64             matrix[b][a]=1;
    65         }
    66         color_Painting(1,0);
    67         System.out.println(res);
    68     }
    69 }

      代码2:

     1 import java.util.*;
     2 
     3 public class Main {
     4     
     5     static int n;    //学生人数
     6     static int m;    //关系
     7     //邻接矩阵
     8     static int matrix[][];
     9     //room[i][j]=z代表教室room[i]的第j个座位坐着同学z
    10     static int room[][];
    11     //room_num[i]存储教室room[i]目前坐了多少位同学
    12     static int room_num[];
    13     static int res=1000;
    14     
    15     static void sit(int stu,int pos) {    //stu表示第stu个学生,pos表示目前用了pos个教室
    16         if(pos>=res) {
    17             return;
    18         }
    19         if(stu>n) {
    20             res=res<pos?res:pos;
    21             return;
    22         }
    23         //判断前面1~pos个教室能不能放入同学stu
    24         for(int i=1;i<=pos;i++) {
    25             //对于教室room[i],只要同学stu不认识里面的其他所有同学即可放入,可以判断stu在此教室不认识的人数是否等于room_num[i]
    26             int total=0;    //统计stu在此教室room[i]不认识的人数
    27             for(int j=1;j<=room_num[i];j++) {
    28                 if(matrix[stu][room[i][j]]==0) {
    29                     total++;
    30                 }
    31             }
    32             //stu不认识教室room[i]里面的所有人
    33             if(total==room_num[i]) {
    34                 room[i][++room_num[i]]=stu;    //放入stu
    35                 sit(stu+1,pos);    //考虑下一位同学,因为没有开辟新的教室,所以还是只用了pos个教室
    36                 //回溯的原因:学生stu虽然可以放在教室room[a],但也许可以放入room[b],这两种放法对所需开辟的最小教室量是不同的,所以需要枚举所有情况
    37                 room_num[i]--;
    38             }
    39         }
    40         //来到此步,说明教室1~pos都放不下学生stu,必须开辟新的教室
    41         room[pos+1][1]=stu;    //将stu放入新的教室
    42         room_num[pos+1]++;
    43         sit(stu+1,pos+1);
    44         room_num[pos+1]--;    //回溯
    45     }
    46 
    47     public static void main(String[] args) {
    48         Scanner reader=new Scanner(System.in);
    49         n=reader.nextInt();
    50         m=reader.nextInt();
    51         matrix=new int[n+1][n+1];
    52         room=new int[101][101];
    53         room_num=new int[101];
    54         //读入边
    55         for(int i=1;i<=m;i++) {
    56             int one=reader.nextInt();
    57             int two=reader.nextInt();
    58             matrix[one][two]=1;
    59             matrix[two][one]=1;
    60         }
    61         sit(1,0);
    62         System.out.println(res);
    63     }
    64 
    65 }

    16:53:43

    2018-08-11

  • 相关阅读:
    LinkedHashMap源码学习
    HashMap源码学习
    Java中"或"运算与"与"运算快慢的三三两两
    Java源码记录
    SpringBoot系列随笔
    分布式事物
    分布式事物
    部署spring boot + Vue遇到的坑(权限、刷新404、跨域、内存)
    一次使用存储过程游标遇到的坑
    UML简单介绍—类图详解
  • 原文地址:https://www.cnblogs.com/chiweiming/p/9459726.html
Copyright © 2020-2023  润新知