• Gym


    Gym - 102785B Gremlins attack!

    题目:[https://vjudge.net/problem/Gym-102785B/origin]

    题意:给一个n*n的矩阵,里面有m个小精灵想到边界去,但是只能走关了灯的地方,现在给你k个灯可以关闭的位置,给的顺序就是关的顺序,请问在关第几盏灯时至少有一个小精灵能出去,小精灵一在边界就等于出去了,如果开始时就有小精灵在边界,则输出零。

    思路:用并查集把可以关灯的位置和它四个方向连起来,但是不是全部连,只有同样是可以关灯的位置或者是小精灵的位置可以连,然后设一个虚拟点start把小精灵和这个点都连上,再设一个虚拟点end表示出口,把边界上的关灯位置和这个点都连上。对于关灯位置边输入边执行以上操作,当getfa(start)=getfa(end)时,说明有小精灵可以出去,后面的灯都不用关了。

    #include<bits/stdc++.h>
    using namespace std;
    #define mo 9901
    #define ll long long
    #define inf 0x7f7f7f
    #define N 250010
    ll read()
    {
    	ll x=0,f=1;char ch=getchar();
    	while (ch<'0'||ch>'9') {if (ch=='-') f=-1;ch=getchar();}
    	while (ch>='0'&&ch<='9') {x=(x<<3)+(x<<1)+(ll)(ch-'0');ch=getchar();}
    	return x*f;
    }
    int n,dad[N],a[505][505],sta,ed;
    int dx[4]={0,1,0,-1};
    int dy[4]={-1,0,1,0};
    int m,k,ans;
    bool check(int x,int y)
    {
    	if (x==0||y==0||x==n-1||y==n-1)
    		return true;
    	return false;
    }
    int getfa(int x)
    {
    	return x==dad[x]?x:dad[x]=getfa(dad[x]);
    }
    void link(int x,int y)
    {
    	int xx=getfa(x),yy=getfa(y);
    	if (xx!=yy) dad[xx]=yy;
    }
    void uni(int x,int y)
    {
    	if (check(x,y)) link(x*n+y,ed);
    	for (int i=0;i<4;i++)
    	{
    		int nx=x+dx[i],ny=y+dy[i];
    		if (nx<0||ny<0||nx>n-1||ny>n-1) continue;
    		if (a[nx][ny]==1) 
    			link(x*n+y,sta);
    		if (a[nx][ny]==2)
    			link(x*n+y,nx*n+ny);
    	}
    }
    int main()
    {
    	ios::sync_with_stdio(false);
    	cin>>n>>m>>k;
    	for (int i=0;i<=n*n+5;i++)
    		dad[i]=i;
    	ans=-1;
    	sta=n*n+1,ed=n*n+2;
    	for (int i=1;i<=m;i++)
    	{
    		int x,y;
    		cin>>x>>y;
    		if (check(x,y)) ans=0;
    		a[x][y]=1;
    	}
    	for (int i=1;i<=k;i++)
    	{
    		int x,y;
    		cin>>x>>y;
    		a[x][y]=2;
    		if (ans!=-1) continue;
    		uni(x,y);
    		if (getfa(sta)==getfa(ed))
    			ans=i;
    	}
    	cout<<ans<<endl;
    	return 0;
    }
    
  • 相关阅读:
    VS2008下编的程序生成的EXE 在没有安装VS2008的计算机上能运行
    GDI+使用小记
    双缓冲技术绘图
    INI文件格式及其读写
    缩放图片并保存
    按值传递&&按引用传递&&按地址传递
    傻瓜式制作的U盘winpe(支持4G以上U盘)速度超快
    vi 命令大全
    fopen和open的区别
    Linux下Socket网络编程,文件传输,数据传输的C语言例子
  • 原文地址:https://www.cnblogs.com/71-111/p/14176203.html
Copyright © 2020-2023  润新知