zoukankan      html  css  js  c++  java
  • Codeforces

    题意:

      给出n个点,m条边的无向图。对于图中的每个点存在当前点权vi和目标点权ti。每次操作可以将同一条边相连的两个点的当前点权同时增加或减少任意值,可以操作任意次。问是否能将所有点的当前点权变成目标点权。

    题解:

      设改变点权为目标点权减去当前点权。偶数距离的点可以共享改变点权,奇数距离的点可以同时变更改变点权。若存在某个环,使得两个点之间既存在奇数距离,又存在偶数距离。那么两组点之间就共通了,这时判断改变点权和是否是偶数即可。否则判断两组点改变点权和是否相等以供消掉。

    #include <bits/stdc++.h>
    using namespace std;
    const int N = 2e5+10;
    typedef long long ll;
    int casee;
    int n, m, tot;
    int x, y;
    ll v1, v2;
    int v[N], t[N];
    bool flag;
    int visit[N];
    int head[N], nxt[N<<1], to[N<<1];
    void dfs(int now, int state) {
        visit[now] = state + 2;
        if(state & 1)
            v1 += t[now] - v[now];
        else
            v2 += t[now] - v[now];
    
        for(int i = head[now]; ~i; i = nxt[i]) {
            int index = to[i];
            if(visit[index]) {
                if(visit[index] == visit[now])
                    flag = true;
                continue;
            }
            
            dfs(index, state^1);
        }
    }
    int main() {
        scanf("%d", &casee);
        while(casee--) {
            flag = false;
            tot = 0;
            v1 = v2 = 0;
            scanf("%d%d", &n, &m);
            memset(head, -1, sizeof(int) * (n+2));
            memset(visit, 0, sizeof(int) * (n+2));
    
            for(int i = 1; i <= n; i++)
                scanf("%d", &v[i]);
            for(int i = 1; i <= n; i++)
                scanf("%d", &t[i]);
            while(m--) {
                scanf("%d%d", &x, &y);
                to[++tot] = y; nxt[tot] = head[x]; head[x] = tot;
                to[++tot] = x; nxt[tot] = head[y]; head[y] = tot;
            }
    
            dfs(1, 0);
    
            if((flag && (v1+v2+1 & 1)) || (!flag && v1 == v2))
                puts("YES");
            else
                puts("NO");
        }
    }
    C++
    package main
    import (
        "fmt"
        "bufio"
        "io"
        "os"
    )
    const N int = 2e5+10
    var casee int
    var n, m, tot int
    var x, y int
    var v1, v2 int64
    var flag bool
    var visit [N]int
    var v, t [N]int
    var head [N]int
    var nxt, to [N<<1]int
    func dfs (now, state int) {
        visit[now] = state + 2
        if (state & 1) > 0 {
            v1 += int64(t[now] - v[now])
        } else {
            v2 += int64(t[now] - v[now])
        }
        for i := head[now]; i > 0; i = nxt[i] {
            var index int = to[i]
            if visit[index] > 0 {
                if visit[index] == visit[now] {
                    flag = true
                }
                continue
            }
            dfs(index, state^1)
        }
    }
    func main() {
        var input io.Reader = bufio.NewReader(os.Stdin)
        for fmt.Fscan(input, &casee); casee > 0; casee-- {
            v1 = 0
            v2 = 0
            tot = 0
            flag = false
            head = [N]int{}
            visit = [N]int{}
    
            fmt.Fscan(input, &n)
            fmt.Fscan(input, &m)
            for i := 1; i <= n; i++ {
                fmt.Fscan(input, &v[i])
            }
            for i:= 1; i <= n; i++ {
                fmt.Fscan(input, &t[i])
            }
            for ; m > 0; m-- {
                fmt.Fscan(input, &x)
                fmt.Fscan(input, &y)
                tot++; to[tot] = y; nxt[tot] = head[x]; head[x] = tot
                tot++; to[tot] = x; nxt[tot] = head[y]; head[y] = tot
            }
    
            dfs(1, 0)
            
            if ((flag && (v1+v2+1) % 2 != 0) || (!flag && v1 == v2)) {
                fmt.Println("YES")
            } else {
                fmt.Println("NO")
            }
        }
    }
    Go
  • 相关阅读:
    C# Task ContinueWith的实现
    C# Task 是什么?返回值如何实现? Wait如何实现
    C# ExecutionContext 实现
    C# Barrier 实现
    C# CountdownEvent实现
    C# SemaphoreSlim 实现
    C# ManualResetEventSlim 实现
    C# Monitor实现
    C# SpinLock实现
    C# SpinWait 实现
  • 原文地址:https://www.cnblogs.com/Pneuis/p/15129292.html
Copyright © 2011-2022 走看看