沈阳集训day7

xiaoxiao2021-02-28  101

吐槽&记录 突然才知道自己太菜了,今天t1又因为输出的时候少输出了一个换行符报零,加上就A,真伤心…linux换行和空格是一个意思啊…t3正解过了


越狱(break)


【问题描述】

Michael为救哥哥身陷囹圄,被关进foxriver监狱。为准备越狱,他需要散布消息给监狱中其他人来共同协作,但是监狱中鱼龙混杂,分成各个小团体,内部消息传递单向传输。问题1:初始至少需要向多少个透漏消息,使得监狱内所有人都获知消息。 问题2,至少需要添加几条传输线路(边),使任意向一个人散步消息后,经过若干次传送,监狱内所有的人最终都能得到消息。


【输入格式】

从文件break.in中输入数据。 输入的第一行包含一个整数 N:监狱人数(2 <= N <= 100)。用前 N 个正整数标识每个人。接下来 N 行中每行都表示一个消息传递列表(分发列表)。第 i+1 行包括 i 的接收消息的人的标识符。每个列表用 0 结束。空列表只用一个 0 表示。


【输出格式】

输出到文件break.out中。 输出的第一行包含一个正整数:问题1的解。第二行应该包含问题2的解。


【样例输入】

5 2 4 3 0 4 5 0 0 0 1 0


【样例输出】

1 2

2A代码…显然tarjan一下然后统计出入度就可以了

#include<iostream> #include<cstring> #include<cstdio> #include<vector> #define MAXN 100+10 using namespace std; vector<int>G[MAXN]; int timer,N,viss[MAXN],dfnn[MAXN],loww[MAXN],stackk[MAXN],t[MAXN],topp,innn[MAXN],outtt[MAXN],cnt,ccc; void tarjan(int x){ viss[x]=true;//viss表示在栈中 stackk[++topp]=x; dfnn[x]=++timer; loww[x]=timer; int size=G[x].size(); for(register int i=0;i<size;i++){ int v=G[x][i]; if(!dfnn[v]){//如果v没有走过 tarjan(v); loww[x]=min(loww[x],loww[v]); }else{ if(viss[v]){//在栈中,则用其dfnn值来更新x loww[x]=min(loww[x],dfnn[v]); } } } if(loww[x]==dfnn[x]){ viss[x]=false; cnt++; t[x]=cnt; while(stackk[topp]!=x){ viss[stackk[topp]]=false; t[stackk[topp]]=cnt; topp--; } topp--; } } int main(){ freopen("break.in","r",stdin); freopen("break.out","w",stdout); scanf("%d",&N); for(register int i=1;i<=N;i++){ int tempp; while(scanf("%d",&tempp)&&tempp){ if(tempp!=i) G[i].push_back(tempp); } } for(register int i=1;i<=N;i++){ if(!dfnn[i]) tarjan(i);//找出强连通分量之后 ccc++; } if(ccc==1){ printf("1\n0\n"); return 0; } for(register int i=1;i<=N;i++){ int size=G[i].size(); for(register int j=0;j<size;j++){ int v=G[i][j]; if(t[i]!=t[v]){ outtt[t[i]]++; innn[t[v]]++; } } } int innh=0,outth=0; for(register int i=1;i<=cnt;i++){ if(innn[i]==0) innh++; if(outtt[i]==0) outth++; } printf("%d\n",innh); int maxn=max(innh,outth); printf("%d\n",maxn); return 0; }

用的不是linux,自认倒霉


分科


【问题描述】

又到了新高一年级文理分科的时候了,每年的这个时候都比较伤感,因为有的要离开到其他班,有的新加入班级。负责安排座位的大川同学制定了这样的计划: 比如A和B都是本班学生且是好朋友,A分到了其他班,而C则是外班进入这个班的,C和A并不熟悉,而C和B关系很好,那么小x为了照顾A和C的情绪,就会让B坐在A的位置,C坐在B的位置。每个学生都只愿意坐到自己好朋友的座位或自己原来的座位。 当然,实际情况可能很复杂,比如一个班里的同学之间关系不一定好,外班进来的可能和本班很多人关系都很好。 现在告诉你,和大川所在班有关系的人一共有n个人,大川想知道有没有一个合理的方案来满足自己的座位安排计划。


【输入格式】

从文件class.in中输入数据。 本题为多组数据,第一行一个整数M,表示有M组测试数据。 对于每组测试数据,每组的第一行一个整数n,表示一共有n个人和这个班有关系。 接下来一行n个整数,第i个整数表示第i个人是否是本班学生(0表示不是,1表示是,分到其他班的也算是本班学生) 接下来一行n个整数,第i个整数表示第i个人是否要分到其他班(0表示留在本班,1表示分到其他班,如果第i个人是由外班分进来的,那么第i个整数就是一个随机整数,没有实际意义) 接下来是一个n行n列的一个二维矩阵,第i行第j列的数表示第i个人和第j个人是否关系很好(1表示认识,0表示0 认识),对角线上是0,自己一定认识自己


【输出格式】

输出到文件class.out中。 每组数据,如果存在一个方案,输出 “ˆ_ˆ”(不含引号)。 如果没有方案,输出 “T_T”(不含引号)。都是半角字符。


【样例输入】

1 3 1 1 0 0 1 0 0 1 1 1 0 0 1 0 0


【样例输出】

ˆ_ˆ


【数据规模与约定】

对于 30% 的数据满足 1 ≤ n ≤ 12。 对于 100% 的数据满足 1 ≤ n ≤ 50,1 ≤ T ≤ 20。 1A代码,二分图匈牙利跑得飞快

#include<iostream> #include<cstring> #include<cstdio> #include<vector> #define MAXN 300+10 using namespace std; int M,n; int a[MAXN],b[MAXN],G[MAXN][MAXN],girl[MAXN]; bool visit[MAXN]; bool find(int x){ if(visit[x]) return false; for(int i=1;i<=n;i++){ if(G[x][i]&&(!visit[i])){ visit[i]=true; if(girl[i]==-1||find(girl[i])){//还没有男友或者虽然名花有主但是可以给主再找个女友 girl[i]=x; return true; } } } return false; } int main(){ freopen("class.in","r",stdin); freopen("class.out","w",stdout); scanf("%d",&M); while(M--){ scanf("%d",&n); for(register int i=1;i<=n;i++){//1是本班 scanf("%d",&a[i]); } for(register int i=1;i<=n;i++)scanf("%d",&b[i]);//1为到其他班,0为留在本班,其他表示是其他班分进来的 for(register int i=1;i<=n;i++){ for(register int j=1;j<=n;j++){ scanf("%d",&G[i][j]); if(G[i][j]==1&&a[i]==1&&a[j]==0) G[i][j]=0;//不连向外班异班的j无论转不转来,本班的i不转,所以本班不连外班,外班可以连本班 if(G[i][j]==1&&a[i]==1&&b[i]==1) G[i][j]=0; //本班转到外班,所有他到别人的关系均断 if(G[i][j]==1&&a[i]==0&&(b[i]==0||b[i]==1)) G[i][j]=0; //是异班,不转到本班,与本班的关系断 if(G[i][j]==1&&a[i]==0&&a[j]==0&&b[i]!=0&&b[i]!=1) G[i][j]=0;//转到本班,与原来的朋友断交 } } for(register int i=1;i<=n;i++){ G[i][i]=1; if(a[i]==1&&b[i]==1)G[i][i]=0; if(a[i]==0&&b[i]!=0&&b[i]!=1)G[i][i]=0; } bool judge=true; memset(girl,-1,sizeof(girl)); for(int i=1;i<=n;i++){ if(a[i]==1&&b[i]==1)continue; if(a[i]==0&&(b[i]==0||b[i]==1)) continue; memset(visit,false,sizeof(visit)); if(!find(i)){ judge=false; break; } } if(judge) printf("^.^\n"); else printf("T.T\n"); } return 0; }
转载请注明原文地址: https://www.6miu.com/read-45513.html

最新回复(0)