您的位置:首页 > 其它

codeforces 650c

2016-04-10 15:56 246 查看
求最长路,相同的点用并查集缩点。。 不得不吐槽下这个博客,退出按键找了半天,重新登录这个号后,发表文章还是显示的那个号。本来写好了的题解,一下就没了,懒得重写了。#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<vector>
#include<string.h>
using namespace std;
#define maxn 1000005

int n,m;
struct node
{
int x,y,w,id;
node(int x=0,int y=0,int w=0,int id=0):x(x),y(y),w(w),id(id){}
friend bool operator<(const node x,const node y)
{
return x.w<y.w;
}
};
struct node a[maxn];
struct edge
{
int en,next;
}E[maxn*6];
int p[maxn],fa[maxn],dis[maxn],vis[maxn];
int num;
void init()
{
memset(p,-1,sizeof(p));
num=0;
}
void add(int st,int en)
{
E[num].en=en;
E[num].next=p[st];
p[st]=num++;
}
int findfa(int x)
{
if(x==fa[x])
return x;
return fa[x]=findfa(fa[x]);
}
void dfs(int id)
{
vis[id]=1;
dis[id]=0;
for(int i=p[id];i!=-1;i=E[i].next)
{
int en=E[i].en;
if(!vis[en])
{
dfs(en);
dis[id]=max(dis[id],dis[en]+1);
}
else dis[id]=max(dis[id],dis[en]+1);
}

}
vector<node>v[maxn];//用于行
vector<node>v2[maxn];//用于列
int main()
{

int cnt,i,j;
while(scanf("%d%d",&n,&m)!=EOF)
{
init();
for(i=0;i<=n;i++)
{
v[i].clear();
v2[i].clear();
}
cnt=0;
for(i=0;i<n;i++)
{
for(j=0;j<m;j++)
{
int x;
scanf("%d",&x);
++cnt;
a[cnt]=node(i,j,x,cnt);
v[i].push_back(node(i,j,x,cnt));
}
}
for(i=0;i<=cnt;i++)
fa[i]=i;
for(i=0;i<n;i++)
{
sort(v[i].begin(),v[i].end());//排序
for(j=1;j<m;j++)
{
if(v[i][j].w==v[i][j-1].w)
{
int tx=findfa(v[i][j-1].id);
int ty=findfa(v[i][j].id);
fa[ty]=tx;//并查集缩点
}
}
}
for(i=0;i<m;i++)
{
for(j=0;j<n;j++)
{
v2[i].push_back(a[j*m+i+1]);
}
}

for(i=0;i<m;i++)
{
sort(v2[i].begin(),v2[i].end());
for(j=1;j<n;j++)
{
if(v2[i][j].w==v2[i][j-1].w)
{
int tx=findfa(v2[i][j-1].id);
int ty=findfa(v2[i][j].id);
fa[ty]=tx;
}
}
}
for(i=0;i<n;i++)
{
for(j=1;j<m;j++)
{
if(v[i][j].w!=v[i][j-1].w)
{
int tx=findfa(v[i][j-1].id);
int ty=findfa(v[i][j].id);
add(ty,tx);//行建边
}
}
}
for(i=0;i<m;i++)
{
for(j=1;j<n;j++)
{
if(v2[i][j].w!=v2[i][j-1].w)
{
int tx=findfa(v2[i][j-1].id);
int ty=findfa(v2[i][j].id);

4000
add(ty,tx);//列建边
}
}
}
memset(dis,0,sizeof(dis));
memset(vis,0,sizeof(vis));
/*for(i=1;i<=12;i++)
{
printf("%d ",fa[i]);

}
printf("*** \n");*/
for(i=1;i<=cnt;i++)
{
int tx=findfa(i);
if(!vis[tx])
{

dfs(tx);//找最长路 用dis记录
}
}
//cout<<dis[1]<<endl;
for(i=0;i<n;i++)
{
for(j=0;j<m;j++)
{
int ans=dis[findfa(a[(i)*m+j+1].id)];
printf("%d",ans+1);
if((j+1)!=m)
printf(" ");
else puts("");
}
}
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: