3 条题解

  • 2
    @ 2023-7-1 1:48:42

    思路:

    1. 定义结构体node,表示每个操作的信息,包括u(元素1)、v(元素2)和op(操作类型)。
    2. 读取输入的n和m,分别表示元素个数和操作个数。
    3. 循环读取每个操作的信息,并保存到结构体数组a中,同时将操作涉及到的元素保存到数组b中。
    4. 对数组b进行排序,并使用unique函数去重,得到不重复的元素个数res。
    5. 遍历操作数组a,将每个操作中的元素映射到范围[1, res]内,通过lower_bound函数找到元素在数组b中的位置。
    6. 初始化并查集的根节点数组fa,将每个元素的根节点初始化为自身。
    7. 遍历操作数组a,根据操作类型进行合并操作:
      • 如果操作类型为"even",判断两个元素所在集合的偶数位置和奇数位置是否属于同一个集合,如果是,则输出当前操作的序号减1,并结束程序;否则,将集合中的元素进行合并。
      • 如果操作类型为"odd",判断两个元素所在集合的偶数位置和奇数位置是否属于同一个集合,如果是,则输出当前操作的序号减1,并结束程序;否则,将集合中的元素进行合并。
    8. 如果没有输出序号,则输出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
      @ 2023-6-30 17:12:17

      image image

      #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
        @ 2023-7-4 3:10:53
        #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
        上传者