3 条题解
-
2
思路:
- 定义结构体node,表示每个操作的信息,包括u(元素1)、v(元素2)和op(操作类型)。
- 读取输入的n和m,分别表示元素个数和操作个数。
- 循环读取每个操作的信息,并保存到结构体数组a中,同时将操作涉及到的元素保存到数组b中。
- 对数组b进行排序,并使用unique函数去重,得到不重复的元素个数res。
- 遍历操作数组a,将每个操作中的元素映射到范围[1, res]内,通过lower_bound函数找到元素在数组b中的位置。
- 初始化并查集的根节点数组fa,将每个元素的根节点初始化为自身。
- 遍历操作数组a,根据操作类型进行合并操作:
- 如果操作类型为"even",判断两个元素所在集合的偶数位置和奇数位置是否属于同一个集合,如果是,则输出当前操作的序号减1,并结束程序;否则,将集合中的元素进行合并。
- 如果操作类型为"odd",判断两个元素所在集合的偶数位置和奇数位置是否属于同一个集合,如果是,则输出当前操作的序号减1,并结束程序;否则,将集合中的元素进行合并。
- 如果没有输出序号,则输出m。
#include <bits/stdc++.h> using namespace std; int n,m,tot,res,b[100010],fa[100010]; struct node { int u,v; string op; } a[100010]; inline int find(int x) { if(fa[x]==x) return x; return fa[x]=find(fa[x]); } int main() { scanf("%d%d",&n,&m); for(register int i=1;i<=m;i++) { scanf("%d%d",&a[i].u,&a[i].v); cin>>a[i].op; b[++tot]=a[i].u; b[++tot]=a[i].v; } sort(b+1,b+1+tot); res=unique(b+1,b+1+tot)-(b+1); for(register int i=1;i<=m;i++) { a[i].u=lower_bound(b+1,b+1+res,a[i].u-1)-b; a[i].v=lower_bound(b+1,b+1+res,a[i].v)-b; } for(register int i=1;i<=2*res;i++) fa[i]=i; for(register int i=1;i<=m;i++) { if(a[i].op=="even") { if(find(a[i].u)==find(a[i].v+res)||find(a[i].u+res)==find(a[i].v)) { printf("%d",i-1); return 0; } fa[find(a[i].u)]=find(a[i].v); fa[find(a[i].u+res)]=find(a[i].v+res); } else { if(find(a[i].u)==find(a[i].v)||find(a[i].u+res)==find(a[i].v+res)) { printf("%d",i-1); return 0; } fa[find(a[i].u)]=find(a[i].v+res); fa[find(a[i].u+res)]=find(a[i].v); } } printf("%d",m); return 0; }
-
2
#include <bits/stdc++.h> using namespace std; const int N=10005; struct node{ int l,r,ans; }que[N]; char str[10]; int n,m,k,s,t,a[N],tot,fa[N],d[N]; int getfa(int x){ if (x==fa[x]) return x; int p=getfa(fa[x]); d[x]^=d[fa[x]]; return fa[x]=p; } int main(){ freopen("in.txt","r",stdin); cin>>n>>m; for (int i=1;i<=m;++i){ cin>>que[i].l>>que[i].r>>str; que[i].ans=(str[0]=='e'?0:1); a[++tot]=que[i].l-1;//离散化 a[++tot]=que[i].r; } sort(a+1,a+1+tot); n=unique(a+1,a+1+tot)-a-1; for (int i=1;i<=n;++i) fa[i]=i; for (int i=1;i<=m;++i){ //求出离散化后的值 int x=lower_bound(a+1,a+1+n,que[i].l-1)-a; int y=lower_bound(a+1,a+1+n,que[i].r)-a; int p=getfa(x); int q=getfa(y); if (p==q) {//已经在同一集合内 if (d[x]^d[y]!=que[i].ans) {//矛盾,输出 cout<<i-1<<"\n";return 0; } } else {//不在同一个集合,合并 fa[p]=q;d[p]=d[x]^d[y]^que[i].ans; } } cout<<m<<"\n";//没有矛盾 }
-
-1
#include <bits/stdc++.h> #define ll long long using namespace std; const int N = 1e4 + 5, k = N / 2; int n, m, f[N]; unordered_map<int, int> mp; int find(int x) { if (x != f[x]) f[x] = find(f[x]); return f[x]; } void join(int x, int y) { x = find(x), y = find(y); if (x != y) f[x] = y; return ; } int calc(int x) { if (mp.count(x) == 0) mp[x] = ++n; return mp[x]; } int main() { ios::sync_with_stdio(false); cin.tie(0); cin >> n >> m; n = 0; for (int i = 1; i < N; i++) f[i] = i; for (int i = 1; i <= m; i++) { int a, b; string op; cin >> a >> b >> op; a = calc(a - 1), b = calc(b); if (op == "even") { if (find(a + k) == find(b) || find(a) == find(b + k)) { cout << i - 1; return 0; } join(a, b); join(a + k, b + k); } else { if (find(a + k) == find(b + k) || find(a) == find(b)) { cout << i - 1; return 0; } join(a + k, b); join(b + k, a); } } cout << m; return 0; }
- 1
信息
- ID
- 233
- 时间
- 1000ms
- 内存
- 128MiB
- 难度
- 3
- 标签
- 递交数
- 57
- 已通过
- 30
- 上传者