当前位置: 代码迷 >> 综合 >> Codeforces Round #541 (Div. 2) D. Gourmet choice(DFS+并查集缩点)
  详细解决方案

Codeforces Round #541 (Div. 2) D. Gourmet choice(DFS+并查集缩点)

热度:92   发布时间:2023-11-15 12:13:21.0

题目链接:http://codeforces.com/contest/1131/problem/D

题目大意

题目背景没仔细看,大体意思就是
有n*m的矩阵,然后(i,j)的符号代表
第一类食物的i个和第二类食物的j个的大小关系。
问是否存在满足这个矩阵关系的食物,如果存在则构造出来。

题目分析 

思想:用Dp思想,首先是根据偏序关系来建图,
用小的自底向上去更新大的,
自顶向下我没试过但感觉应该差不多。
此外还有缩点,因为有若干个点其是相等关系,
直接搜下去会有很多情况比如不知道搜到重复的点
是合理的(相等的环)还是非法的(偏序错误)。
缩点用并查集,相等关系的若干个点用其父节点代替。
此外这题前式链向星居然会T而容器不会,,
是初始化时候时间的代码???望大佬解答。。。

#include<bits/stdc++.h>
using namespace std;#define debug puts("YES");
#define rep(x,y,z) for(int (x)=(y);(x)<(z);(x)++)
#define ll long long#define lrt int l,int r,int rt
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define root l,r,rt
#define mst(a,b) memset((a),(b),sizeof(a))
#define pii pair<int,int>
#define fi first
#define se second
#define mk(x,y) make_pair(x,y)
const int mod=1e9+7;
const int maxn=1e3+5;
const int ub=1e6;
ll powmod(ll x,ll y){ll t; for(t=1;y;y>>=1,x=x*x%mod) if(y&1) t=t*x%mod; return t;}
ll gcd(ll x,ll y){return y?gcd(y,x%y):x;}
/*
题目大意:
题目背景没仔细看,大体意思就是
有n*m的矩阵,然后(i,j)的符号代表
第一类食物的i个和第二类食物的j个的大小关系。
问是否存在满足这个矩阵关系的食物,如果存在则构造出来。题目分析:
思想:用Dp思想,首先是根据偏序关系来建图,
用小的自底向上去更新大的,
自顶向下我没试过但感觉应该差不多。
此外还有缩点,因为有若干个点其是相等关系,
直接搜下去会有很多情况比如不知道搜到重复的点
是合理的(相等的环)还是非法的(偏序错误)。
缩点用并查集,相等关系的若干个点用其父节点代替。
此外这题前式链向星居然会T而容器不会,,
是初始化时候时间的代码???望大佬解答。。。
*/
///数据域
int n,m;
char s[maxn][maxn];
int d[maxn<<1];
int flag,v;
int vis[maxn<<1],ans[maxn<<1];
///bcj
int fa[maxn<<1];///
int Find(int x){return (fa[x]==x)?x:fa[x]=Find(fa[x]);
}
void Union(int x,int y){int fx=Find(x),fy=Find(y);if(fx!=fy) fa[fx]=fy;
}
/*
///邻接表
struct node{int u,nxt;
}e[maxn*maxn];
int head[maxn<<1],tot=0;
void init(){mst(head,-1),tot=0;
}
void add(int x,int y){e[tot]=node{y,head[x]};head[x]=tot++;
}
*/
vector<int> g[maxn<<1];void dfs(int x,int val){if(val<=ans[x]) return ;else ans[x]=val;if(vis[x]==1) flag=0;else vis[x]=1;if(flag==0) return ;for(int i=0;i<g[x].size();i++)dfs(g[x][i],val+1);vis[x]=0;
}int main(){scanf("%d%d",&n,&m);///初始化flag=1;///init();rep(i,0,n+m) fa[i]=i;///缩点rep(i,0,n){scanf("%s",s[i]);rep(j,0,m) if(s[i][j]=='=')Union(i,j+n);}///建边rep(i,0,n) rep(j,0,m){int tx=i,ty=j+n;tx=Find(tx),ty=Find(ty);if(s[i][j]=='<') d[ty]=1,g[tx].push_back(ty);else if(s[i][j]=='>') d[tx]=1,g[ty].push_back(tx);}///搜索int tmp=0;rep(i,0,n+m) if(d[i]==0&&fa[i]==i)tmp=1,dfs(i,1);///输出if(flag==0||tmp==0) puts("No");else{puts("Yes");rep(i,0,n) printf("%d ",ans[Find(i)]);puts("");rep(i,0,m) printf("%d ",ans[Find(i+n)]);puts("");}return 0;
}

 

  相关解决方案