在乙個 n*n個方格的西洋棋棋盤上,馬(騎士)可以攻擊的棋盤方格如圖所示。棋盤上某些方格設定了障礙,騎士不得進入
對於給定的 n*n 個方格的西洋棋棋盤和障礙標誌,計算棋盤上最多可以放置多少個騎士,使得它們彼此互不攻擊
輸入格式:
第一行有 2 個正整數n 和 m (1<=n<=200, 0<=m
輸出格式:
將計算出的共存騎士數輸出
輸入樣例#1: 複製
3 2輸出樣例#1: 複製1 13 3
5這個題目和剛剛那個題目很像也是乙個網路流的最大獨立集題目,
既然如此,我們就照著那個題目來分析。
首先我們要把可以兩個互斥的格仔進行分開,然後和之前的一比對,會發現如果兩個任何兩個互斥的騎士他們的橫縱座標之和的奇偶性不相同。
所以這就說明,我們可以像之前一樣,用這個奇偶性把他們分成兩個部分,還是一樣,在同乙個部分的肯定不互斥,不在同乙個部分可能互斥。
這個多了乙個障礙物,我覺得這個可以理解為這個格仔不見了,所以不要管他就可以了。
這個建圖就是 s連線乙個部分,容量就是1,乙個部分與另乙個部分互斥的數相連,容量為inf,另乙個部分和t相連。
那麼這個我們再理解一下,所以這個最大流就意味著,最少的不能佔的地方。
所以 ans=沒有障礙物的總格仔數量 - 最大流,
#include #include#include
#include
#include
#include
#include
#include
#define inf 0x3f3f3f3f
using
namespace
std;
const
int inf = 0x3f3f3f3f
;const
int maxn = 1e5 + 10
;struct
edge
};vector
e;vector
g[maxn];
int level[maxn];//
bfs分層,表示每個點的層數
int iter[maxn];//
當前弧優化
intm;
void init(int
n)void add(int u, int v, int
c)void bfs(int s)//
預處理出level陣列
//直接bfs到每個點}}
}int dfs(int u, int t, int f)//
dfs尋找增廣路}}
return0;
}int maxflow(int s, int
t) }
return
flow;
}bool vis[210][210
];int dx[8] = ;
int dy[8] = ;
intmain()
int s = 0, t = n * n + 1
;
for(int i=1;i<=n;i++)
}else add(ex, t, 1
); }
}int ans =maxflow(s, t);
//printf("%d\n", ans);
printf("
%d\n
", n*n - m -ans);
return0;
}
P3355 騎士共存問題 網路流
在乙個 n n個方格的西洋棋棋盤上,馬 騎士 可以攻擊的棋盤方格如圖所示。棋盤上某些方格設定了障礙,騎士不得進入 對於給定的 n n 個方格的西洋棋棋盤和障礙標誌,計算棋盤上最多可以放置多少個騎士,使得它們彼此互不攻擊 和方格取數一模一樣 只不過相鄰改成了日字 所有的權值都為1 主要要減去m個障礙 ...
P3355 騎士共存問題
題目描述 在乙個 n n個方格的西洋棋棋盤上,馬 騎士 可以攻擊的棋盤方格如圖所示。棋盤上某些方格設定了障礙,騎士不得進入 對於給定的 n n 個方格的西洋棋棋盤和障礙標誌,計算棋盤上最多可以放置多少個騎士,使得它們彼此互不攻擊 輸入格式 第一行有 2 個正整數n 和 m 1 n 200,0 m輸出...
P3355 騎士共存問題
在乙個n n個方格的西洋棋棋盤上,馬 騎士 可以攻擊的棋盤方格如圖所示。棋盤上某些方格設定了障礙,騎士不得進入 對於給定的n n 個方格的西洋棋棋盤和障礙標誌,計算棋盤上最多可以放置多少個騎士,使得它們彼此互不攻擊 輸入格式 第一行有 2 個正整數n 和 m 1 n 200,0 m輸出格式 將計算出...