1924: [Sdoi2010]所驼门王的宝藏
Time Limit: 5 Sec Memory Limit: 128 MBSubmit: 875 Solved: 359
[ Submit][ Status][ Discuss]
Description
Input
第一行给出三个正整数 N, R, C。 以下 N 行,每行给出一扇传送门的信息,包含三个正整数xi, yi, Ti,表示该传送门设在位于第 xi行第yi列的藏宝宫室,类型为 Ti。Ti是一个1~3间的整数, 1表示可以传送到第 xi行任意一列的“横天门”,2表示可以传送到任意一行第 yi列的“纵寰门”,3表示可以传送到周围 8格宫室的“自由门”。 保证 1≤xi≤R,1≤yi≤C,所有的传送门位置互不相同。
Output
只有一个正整数,表示你确定的路线所经过不同藏宝宫室的最大数目。
Sample Input
10 7 7
2 2 1
2 4 2
1 7 2
2 7 3
4 2 2
4 4 1
6 7 3
7 7 1
7 5 2
5 2 1
2 2 1
2 4 2
1 7 2
2 7 3
4 2 2
4 4 1
6 7 3
7 7 1
7 5 2
5 2 1
Sample Output
9
HINT
测试点编号 N R C 1 16 20 20 2 300 1,000 1,000 3 500 100,000 100,000 4 2,500 5,000 5,000 5 50,000 5,000 5,000 6 50,000 1,000,000 1,000,000 7 80,000 1,000,000 1,000,000 8 100,000 1,000,000 1,000,000 9 100,000 1,000,000 1,000,000 10 100,000 1,000,000 1,000,000
Source
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<stack>
#include<queue>
using namespace std;
const int maxn = 1E5 + 10;
const int maxm = 1E6 + 10;
const int mo = 999983;
const int dx[8] = {0,1,0,-1,1,-1,1,-1};
const int dy[8] = {1,0,-1,0,1,1,-1,-1};
int n,R,C,cnt,tot,dfs_clock,low[maxm],r[maxn],c[maxn],typ[maxn],Ans[maxm]
,va[maxm],numr[maxm],numc[maxm],dfn[maxm],belong[maxm],du[maxm],siz[maxm];
vector <int> v1[mo];
vector <int> v2[maxm];
vector <int> v3[maxm];
stack <int> s;
queue <int> Q;
void BFS()
{
for (int i = 1; i <= cnt; i++)
for (int j = 0; j < v2[i].size(); j++) {
int to = v2[i][j];
if (belong[to] == belong[i]) continue;
v3[belong[to]].push_back(belong[i]);
++du[belong[i]];
}
for (int i = 1; i <= tot; i++)
if (!du[i]) Q.push(i);
while (!Q.empty()) {
int k = Q.front(); Q.pop();
Ans[k] = siz[k] + Ans[k];
for (int i = 0; i < v3[k].size(); i++) {
int to = v3[k][i];
Ans[to] = max(Ans[to],Ans[k]);
--du[to];
if (!du[to]) Q.push(to);
}
}
}
void hash_insert(int x,int y,int now)
{
int pos = (1LL*(x-1)*y%mo + y)%mo;
v1[pos].push_back(now);
}
int hash_search(int x,int y)
{
int pos = (1LL*(x-1)*y%mo + y)%mo;
for (int i = 0; i < v1[pos].size(); i++) {
int now = v1[pos][i];
if (r[now] == x && c[now] == y) return now;
}
return 0;
}
void Dfs(int x)
{
low[x] = dfn[x] = ++dfs_clock;
s.push(x);
for (int i = 0; i < v2[x].size(); i++) {
int to = v2[x][i];
if (!dfn[to]) Dfs(to),low[x] = min(low[x],low[to]);
else if (!belong[to]) low[x] = min(low[x],low[to]);
}
if (dfn[x] == low[x]) {
++tot;
for (;;) {
int y = s.top(); s.pop();
belong[y] = tot;
siz[tot] += va[y];
if (y == x) break;
}
}
}
int main()
{
#ifdef DMC
freopen("DMC.txt","r",stdin);
#endif
cin >> n >> R >> C; cnt = n;
for (int i = 1; i <= n; i++) {
scanf("%d%d%d",&r[i],&c[i],&typ[i]);
hash_insert(r[i],c[i],i);
}
for (int i = 1; i <= n; i++) {
if (typ[i] == 1) {
if (!numr[r[i]]) numr[r[i]] = ++cnt;
v2[i].push_back(numr[r[i]]);
}
else if (typ[i] == 2) {
if (!numc[c[i]]) numc[c[i]] = ++cnt;
v2[i].push_back(numc[c[i]]);
}
else {
for (int l = 0; l < 8; l++) {
int xx = r[i] + dx[l];
int yy = c[i] + dy[l];
if (xx <= 0 || xx > R || yy <= 0 || yy > C) continue;
int ret = hash_search(xx,yy);
if (!ret) continue;
v2[i].push_back(ret);
}
}
va[i] = 1;
}
for (int i = 1; i <= n; i++) {
if (numr[r[i]]) v2[numr[r[i]]].push_back(i);
if (numc[c[i]]) v2[numc[c[i]]].push_back(i);
}
for (int i = 1; i <= cnt; i++) if (!dfn[i]) Dfs(i);
BFS(); int ans = 0;
for (int i = 1; i <= tot; i++) ans = max(ans,Ans[i]);
cout << ans;
return 0;
}