Technocup 2021 - Elimination Round 3 CD
C. Peaceful Rooks
題意是每行每列同時只能存在一個點,每次可以對一個點進行橫向移動或縱向移動,現在想要求將這些點都移動到主對角線上所需的最小次數。
思路:對於每個點來說,要麼可以直接移動到所在行(或列)的主對角線上,要麼可以先移動到其他空餘的地方,等其他的點都移動到主對角線上之後,再將這個點移動到主對角線上。
所以實際上我們對某個點可以進行這樣的判斷:
- 如果可以直接移動,那麼就不用進行多餘操作;
- 如果不能直接移動,那麼就開始找有沒有其他可以直接移動的點。
如果在找的過程中發現有的點可以直接移動到主對角線上,那麼在這個點移動之後,其他的點自然可以依次移動的對角線上。
而如果在找的過程中發現有環出現了,即沒有點可以直接移動了,那麼就需要先把初始的點騰位置,然後讓其他的點到主對角線上,最後在把初始點移動到對角線上,可以發現相比可以直接移動的情況,次數多了一次。
之後就是模擬過程,思路不難,但程式碼細節需要注意!
#include<bits/stdc++.h>
#define ll long long
#define inf 0x3f3f3f30f
#define endl '\n'
using namespace std;
const int N = 1e5 + 100;
int n, m, b[N], bj[N], h[N], gg[N], sum;
void dfs(int x, int s)
{
if(bj[x]) //如果成環了
{
gg[h[x]] = 0;
sum += s; //這裡雖然是+s,但是實際上是加的 s + 1,因為是當進入了下一層dfs之後才判斷是否成環。
return ;
}
if(h[x] == x) //如果本來就不需要移動
return ;
if(h[x] != x) //如果需要移動
{
if(gg[h[x]]) //判斷需要移動的這一列上是否有,有的話遞迴騰位置,找到所有在一個集合裡的點
{
bj[x] = 1; //判環標記陣列
dfs(h[x], s + 1); //要移到與所在行相同的一列上
}
else //沒有的話說明可以直接移動,不用騰位置
{
sum += s;
return ;
}
gg[x] = 0; //free點所在的行,防止重複計算
}
return ;
}
void solve()
{
memset(b, 0, sizeof b);
memset(gg, 0, sizeof gg);
memset(h, 0, sizeof h);
sum = 0;
cin >> n >> m;
for(int i = 0; i < m; i ++)
{
int x, y;
cin >> x >> y;
gg[y] = 1; // 所在列標記上
h[y] = x; //壓縮存圖, 第y列x行是點i
b[i] = y; //存點
}
for(int i = 0; i < m; i ++)
if(gg[b[i]])
{
memset(bj, 0, sizeof bj);
dfs(b[i], 1); // 深搜
}
cout << sum << endl;
}
int main()
{
int _;
cin >> _;
while(_ --)
solve();
return 0;
}
相關文章
- Codeforces Round #844 (Div. 1 + Div. 2, based on VK Cup 2022 - Elimination Round) A-D
- 矩陣消元 elimination矩陣
- [20190524]Table Elimination.txt
- [Kick Start] 2021 Round B
- Codeforces Round 962(Div .3)
- Codeforces Round 991 (Div. 3)
- Codeforces Round 981 (Div. 3)
- Codeforces Round 974 (Div. 3)
- Codeforces Round 966 (Div. 3)
- Testing Round 19 (Div. 3)
- Codeforces Round 946 (Div. 3)
- Codeforces Round 962(Div. 3)
- Codeforces Round 962 (Div. 3)
- Codeforces Round 957 (Div. 3)
- Codeforces Round 916 (Div. 3)
- Codeforces Round 954 (Div. 3)
- Codeforces Round 933 (Div. 3)
- Codeforces Round 943 (Div. 3)
- Codeforces Round 950 (Div. 3)
- 牛客周賽 Round 3
- Codeforces Round #690 (Div. 3)
- 2024.11.17 Codeforces Round 988 (Div. 3)
- Codeforces Round 991 (Div. 3) A ~ G
- 源魯杯2024[Round 3] CheckImg
- Codeforces Round 981 (Div. 3)(A~E)
- Codeforces Round 970 (Div. 3)A~F
- Codeforces Round 970 (Div. 3) ABCDEFGH
- Codeforces Round 966 (Div. 3) VP
- Codeforces Round 938 (Div. 3) E
- [20200120]12c Group by Elimination bug.txt
- Codeforces Round 984 (Div. 3) 題解
- Codeforces Round 962 (Div. 3) 題解
- Codeforces Round 957 (Div 3)(A—G題解)
- Codeforces Round 946 (Div. 3) 題解
- 4.4Codeforces Round 935 (Div. 3)
- Codeforces Round #713 (Div. 3)AB題
- Codeforces Round #615 (Div. 3) (題解)
- Codeforces Round 933 (Div. 3) (C-G)