您的位置:首页 > 其它

POJ 2375 Cow Ski Area 增加最小边使图强连通

2016-05-05 19:48 399 查看
题意:一个矩阵图,每一个格子有一个权值,相邻格子之间可以通,条件是一个格子可以走到相邻格子的条件是相邻格子的全是不大于当前格子,问增加多少条边使得每一个格子都可以到达任意格子



想法:tarjan缩点,之后,结果为Max(出度为0点个数,入度为0点个数)

因为这个图,没有孤立点。
#include<iostream>
#include<stdio.h>
#include<cstring>
#include<cstdio>
#include<stack>
using namespace std;
const int N=250000+50;
const int M=2000000+50;
int w,l,n;
int map[505][505];
struct node
{
int v,next;
}e[M];
stack<int>s;
int head
,cnt;
int dfn
,low
,index,col,in
,out
,instack
,paint
;
void Init()
{
while(!s.empty()) s.pop();
memset(head,-1,sizeof(head));
cnt=0;
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
memset(in,0,sizeof(in));
memset(out,0,sizeof(out));
memset(instack,0,sizeof(instack));
memset(paint,0,sizeof(paint));
col=index=0;
}
void add(int a,int b)
{
e[cnt].v=b;
e[cnt].next=head[a];
head[a]=cnt++;
}
int Min(int a,int b)
{
if(a<b) return a;
return b;
}
void tarjan(int u)
{
dfn[u]=low[u]=++index;
instack[u]=1;
s.push(u);
for(int i=head[u];i+1;i=e[i].next)
{
int v=e[i].v;
if(!dfn[v])
{
tarjan(v);
low[u]=Min(low[u],low[v]);
}
else if(instack[v])
{
low[u]=Min(low[u],dfn[v]);
}
}
if(dfn[u]==low[u])
{
++col;
int k=s.top();
while(k!=u)
{
s.pop();
instack[k]=0;
paint[k]=col;
k=s.top();
}
s.pop();
instack[u]=0;
paint[u]=col;
}
}
int main()
{
while(~scanf("%d%d",&w,&l))
{
n=w*l;
Init();
for(int i=1;i<=l;i++)
{
for(int j=1;j<=w;j++)
{
scanf("%d",&map[i][j]);
}
}
for(int i=1;i<=l;i++)
{
for(int j=1;j<=w;j++)
{
int num=(i-1)*w+j;
if(j+1<=w)
{
if(map[i][j]>map[i][j+1])
{
add(num,num+1);
}
else if(map[i][j]<map[i][j+1])
{
add(num+1,num);
}
else
{
add(num,num+1);
add(num+1,num);
}
}
if(i+1<=l)
{
if(map[i][j]>map[i+1][j])
{
add(num,num+w);
}
else if(map[i][j]<map[i+1][j])
{
add(num+w,num);
}
else
{
add(num,num+w);
add(num+w,num);
}
}
}
}
for(int i=1;i<=n;i++)
{
if(!dfn[i]) tarjan(i);
}
for(int i=1;i<=n;i++)
{
for(int j=head[i];j+1;j=e[j].next)
{
int a=i,b=e[j].v;
if(paint[a]!=paint[b])
{
out[paint[a]]++;
in[paint[b]]++;
}
}
}
int inn=0,outn=0,res;
for(int i=1;i<=col;i++)
{
if(!in[i]) inn++;
if(!out[i]) outn++;
}
if(inn>outn) res=inn;
else res=outn;
if(col==1) printf("0\n");
else printf("%d\n",res);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: