第三部分 數據結構 -- 第四章 圖論算法-1347:【例4-8】格子游戲

1347:【例4-8】格子游戲

時間限制: 1000 ms 內存限制: 65536 KB
提交數: 2734 通過數: 1643
【題目描述】
Alice和Bob玩了一個古老的遊戲:首先畫一個n × n的點陣(下圖n = 3)

接着,他們兩個輪流在相鄰的點之間畫上紅邊和藍邊:

直到圍成一個封閉的圈(面積不必爲1)爲止,“封圈”的那個人就是贏家。因爲棋盤實在是太大了(n ≤ 200),他們的遊戲實在是太長了!他們甚至在遊戲中都不知道誰贏得了遊戲。於是請你寫一個程序,幫助他們計算他們是否結束了遊戲?

【輸入】
輸入數據第一行爲兩個整數n和m。m表示一共畫了m條線。以後m行,每行首先有兩個數字(x, y),代表了畫線的起點座標,接着用空格隔開一個字符,假如字符是"D ",則是向下連一條邊,如果是"R "就是向右連一條邊。輸入數據不會有重複的邊且保證正確。

【輸出】
輸出一行:在第幾步的時候結束。假如m步之後也沒有結束,則輸出一行“draw”。

【輸入樣例】
3 5
1 1 D
1 1 R
1 2 D
2 1 R
2 2 D
【輸出樣例】
4


思路: 二維並查集解決的是連通性和傳遞性問題,並且可以動態的維護。任意一個圖中,增加一條邊形成環當且僅當這條邊連接的兩點已經聯通,於是可以將點分爲若干個集合,每個集合對應圖中的一個連通塊。

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cstdlib>
using namespace std;
int n,m,a,b;
char c;
struct node
{
    int x,y;       //橫縱座標
}father[10001][10001],k1,k2;

node find(node k)  //開始找父親
{
    if(father[k.x][k.y].x!=k.x&&father[k.x][k.y].y!=k.y) father[k.x][k.y]=find(father[k.x][k.y]);
    return father[k.x][k.y];
}

int main()
{
    scanf("%d%d",&n,&m);

    for(int i=1;i<=n;i++)
      for(int j=1;j<=n;j++)    //初始化
      {
          father[i][j].x=i;
          father[i][j].y=j;
      }
      
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d%s",&a,&b,&c);
        if(c=='D')    //向下走
        {
            k1=find(father[a][b]);
            k2=find(father[a+1][b]);
        }
        if(c=='R')    //向右走
        {
            k1=find(father[a][b]);
            k2=find(father[a][b+1]);
        }

        if(k1.x==k2.x&&k1.y==k2.y)   //判斷是否連通結束
        {
            cout<<i<<endl;
            return 0;
        }
        else     
            father[k1.x][k1.y]=k2;    //否則合併
   
    }
    cout<<"draw";    //一直未結束
    return 0;
    
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章