这周主要的任务就是做题和思考总结题。这周至少看了老师发的题数量的五分之三,下面通过几个并查集的题来总结这周所学的内容。
认为好的题
P1546最短网络 题意:根据所给出的数据求出连接到每个农场的最小光纤长度 题解:观察出矩阵是对称的,所以在输入的时候把j>i的保留下来生成树,然后对权值进行从小到大的排序,然后进行合并的同时加上权值,当合并的次数减一等于n时结束。 部分代码如下:
for(int i=1;i<=n;i++)
{
fa[i]=i;
for(int j=1;j<=n;j++)
{
cin>>k;
if(j>i)//对称
{
m++;
node[m].x=i;
node[m].y=j;
node[m].w=k;
}
}
}
P1656炸铁路 题意:n个城市,m条铁路,炸掉一条铁路使得某城市无法通过 题解:(看的答案)先枚举一条边被炸,然后合并其他边连的点,看是否有同一个祖先,如果没有则输出 部分代码如下
//1\
bool tem(Node a,Node b)
{
if(a.X==b.X)
return a.Y<b.Y;
return a.X<b.X;
}//结构体排序
//2、
for(int i=1;i<=m;i++)
{
cin>>node[i].X>>node[i].Y;
if(node[i].Y<node[i].X)
{
swap(node[i].X,node[i].Y);//交换
}
}
//3、
sort(node+1,node+1+m,tem);
//4、
for(int i=1;i<=m;i++)
{
for(int j=1;j<=n;j++)
{
fa[j]=j;
}
for(int j=1;j<=m;j++)
{
if(j!=i)
Unite(node[j].X,node[j].Y);//合并
}
for(int j=2;j<=n;j++)
{
if(fa[find(j)]!=fa[find(j-1)])
{
cout<<node[i].X<<" "<<node[i].Y<<endl;
break;
}
}
}
P6121 USACO16OPEN 题意:关掉某农场时,其他农场是否连通 题解:(看的答案) 用fa数组来存放它祖先节点,开始初始化成每一个点自己在一个集合,如果他们不在一个集合,并且有一条边连接他们两个,就把他们合并,操作数+1,如果当前k个农场是开着的,记录合并的次数,如果次数等于k-1,输出YES,否则输出NO(重要思想:反着搜)
P2814家谱 题意:#name一组父子中父亲名字,+name一组父子关系中儿子名字,?Name该人祖先,¥文件结束,按文件顺序输出每一个要找人的祖先 题解:法1:把名字和数字一一对应来做;法2:用map<string,string>p,p[s],s是字符串,和下标道理一样
p2661信息传递 题意:一个人可以到多个人但只能向一个人传递,当玩家从其他玩家那听到自己生日时结束 题解:类似与并查集求最小环
自己的改变
怎么说呢,从行动上看只能说比上学期躺在床上玩手机的时间大大大……幅度减少了,以前是熬夜玩游戏,看小说,现在是熬夜敲代码,写作业。 现在感觉到…充实吗?不全是,痛苦吗?也不全是,应该是感受到进步的喜悦,现在做事更加认真了(就比如说有时晚上在宿舍敲代码或写作业时,舍友打游戏也影响不了我)。对于其他科目来说,虽然没有那么多时间来学,可现在看看书思考思考,和以前学的结合起来,又能做出题,感觉效率也提高了不少。最后最明显的改变是:如果还像以前一样,那我应该还是在宿舍玩游戏或睡懒觉又或是学习课本知识又或是图书馆看书吧,而不是做在电脑前心静下来写博客和刷题与思考题了。