问题描述
早上好,特工W-12,你需要完成的以下的任务。
我们已经渗透到一个叫混乱与祸害的组织中,希望能掌握该组织的管理权。不幸的是,它们似乎已经准备好应对这样的事件了,它们使用了一个很复杂的设计分配管理权力,这使得我们的渗透工作非常艰难。
那家组织的管理系统被分成若干个单位,对于任意两个单位A和B,要么A管理B要么B管理A,同时这个管理关系可以形成环,因此可以出现A管理B、B管理C、C管理A的情况。
我们可以安排特工去渗透到任意一个单位,那将使得我们控制该单位和那个单位直接管理的单位,但是不包括间接管理的单位。比如之前的样例,渗透到A单位会让我们控制A和B,但不能控制C。
对于一个成功的渗透工作来说,我们必须要控制所有的单位才行,否则其他单位会发现我们,同时破坏我们的计划。而你也知道,我们现在从更高的部门那里拿到的经费十分紧缺,我们必须最高效地完成任务。你的任务就是要找出控制单位最少的可行方案。
我们已经渗透到一个叫混乱与祸害的组织中,希望能掌握该组织的管理权。不幸的是,它们似乎已经准备好应对这样的事件了,它们使用了一个很复杂的设计分配管理权力,这使得我们的渗透工作非常艰难。
那家组织的管理系统被分成若干个单位,对于任意两个单位A和B,要么A管理B要么B管理A,同时这个管理关系可以形成环,因此可以出现A管理B、B管理C、C管理A的情况。
我们可以安排特工去渗透到任意一个单位,那将使得我们控制该单位和那个单位直接管理的单位,但是不包括间接管理的单位。比如之前的样例,渗透到A单位会让我们控制A和B,但不能控制C。
对于一个成功的渗透工作来说,我们必须要控制所有的单位才行,否则其他单位会发现我们,同时破坏我们的计划。而你也知道,我们现在从更高的部门那里拿到的经费十分紧缺,我们必须最高效地完成任务。你的任务就是要找出控制单位最少的可行方案。
输入格式
第一行包含一个整数n,表示该组织的单位数。接下来n行每行n个二进制位。在其中的第i行第j列位置,若为1表示i单位控制j单位,否则j单位控制i单位。
输出格式
共一行,第一个整数ans表示最少的控制单位数量,接下来ans个整数表示任意一组可行的方案。
样例输入
样例1:
2
00
10
样例2:
3
010
001
100
样例3:
5
01000
00011
11001
10100
10010
2
00
10
样例2:
3
010
001
100
样例3:
5
01000
00011
11001
10100
10010
样例输出
样例1:
1 2
样例2:
2 1 2
样例3:
2 2 3
1 2
样例2:
2 1 2
样例3:
2 2 3
数据规模和约定
30%的数据n<=10。
50%的数据n<=30。
100%的数据n<=75。
50%的数据n<=30。
100%的数据n<=75。
保证n*n的01矩阵中所有的i行i列位置为0,i行j列和j行i列两个位置恰好一个为1一个为0(i≠j)。
这道题隐含了一个条件,对角线上的0其实可以看为1,最后题目就演变成了找出最少的字符串数,使字符串的值全变为1。
开始本来想用暴力法枚举,看了下数据量与算法量觉得肯定会超时,就用了广搜进行判断。
不过20组数据还是有2组超时了...只有90分。
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Scanner;
public class infiltration {
static String []m;
static String end="";
static int n;
static class edge
{
String now;//存储字符串
int count; //存储步数
int a[]; //存储已经加了的编号
public edge(String now,int count)
{
this.now=now;
this.count=count;
a=new int[76];
}
public void input(int i)//加入一个新的编号
{
count++;
a[count-1]=i;
}
}
public static void bfs()
{
LinkedList<edge> a =new LinkedList<>();//用list模仿队列
HashSet<String> hashSet=new HashSet<>();//防止重复的字符串
for(int i=1;i<m.length;i++)
{
hashSet.add(m[i]);
edge e=new edge(m[i], 0);
e.input(i);
a.add(e);
if(m[i].equals(end))
{
System.out.print(1+" "+i);
return;
}
}
boolean flag=true;
while(!a.isEmpty()&&flag)//进行bsf广搜
{
edge p=a.get(0);
a.remove(0);
for(int i=p.a[p.count-1]+1;i<=n;i++)
{
String b=Add(p.now, m[i]);
if(!hashSet.contains(b))
{
edge k=new edge(p.now, p.count);
for(int w=0;w<p.count;w++)
{
k.a[w]=p.a[w];
}
k.now=b;
k.input(i);
hashSet.add(b);
a.add(k);
if(b.equals(end))
{
flag=false;
break;
}
}
b=p.now;
}
}
edge ed=a.get(a.size()-1);
System.out.print(ed.count+" ");
for(int i=0;i<ed.count;i++)
{
System.out.print(ed.a[i]+" ");
}
}
public static String Add(String a,String b)
{
char[] A=a.toCharArray();
char[] B=b.toCharArray();
String C="";
for(int i=0;i<a.length();i++)
{
if(A[i]=='1'||B[i]=='1')
A[i]='1';
C=C+A[i];
}
return C;
}
public static void main(String args[])
{
Scanner sc=new Scanner(System.in);
n=sc.nextInt();
m=new String[n+1];
for(int i=1;i<=n;i++)
{
end=end+'1';
m[i]=sc.next();
char[]M=m[i].toCharArray();//处理字符串
m[i]="";
M[i-1]='1';
for(int j=0;j<n;j++)
{
m[i]=m[i]+M[j];
}
}
bfs();
}
}