设为首页 加入收藏

TOP

正睿暑期培训day1考试(二)
2019-09-03 03:45:18 】 浏览:76
Tags:暑期 培训 day1 考试
;= r) { int mid = (l + r) >> 1; if(x <= a[mid].r2) ret = mid,r = mid - 1; else l = mid + 1; } return ret; } int find(int x) { while(1) { int p = erfen(x); if(a[p].l2 > x || a[p].r2 < x) return x; int tmp = a[p].l2 - a[p].l1; x = x - (x - a[p].l2) / tmp * tmp; while(x >= a[p].l2) x -= tmp; } } int main() { n = read(),m1 = read(),m2 = read(),Q = read(); for(int i = 1;i <= m1;++i) { int x = read();char c; scanf("%c",&c); b[i] = make_pair(x,c); } for(int i = 1;i <= m2;++i) { a[i].l1 = read();a[i].r1 = read();a[i].l2 = read();a[i].r2 = read(); } sort(a + 1,a + m2 + 1,cmp); for(int i = 1;i <= m1;++i) ans[find(b[i].first)] = b[i].second; while(Q--) { int x = find(read()); if(!ans.count(x)) puts("?"); else putchar(ans[x]),puts("");; } return 0; }

C

先考虑一下无解的情况。

1.m为奇数肯定无解。这个很显然,每条路径长度都要是偶数,每条边都要走恰好一遍。显然边数为偶数
2.如果存在某个点的度数为偶数,肯定无解。考虑一个点肯定要作为恰好一条路径的端点,在这条路径中这个点被走了奇数次。而其他的每条路径这个点肯定都被走了偶数次。所以这个点的度数肯定为奇数。

然后先不考虑路径长度为偶数的问题。那么只要建一个虚点,向所有点连一条虚边,这个每个点的度数都是偶数。跑一边欧拉回路,删掉虚点和虚边。就得到了一个答案。

然后考虑如何处理长度为偶数的限制。如果我们把边两两配对建一个新图(因为边数为偶数,所以一定可以做到),再按照上面的方法跑。最后把边拆回成原来的边即可。

然后考虑如何将边配对。先建立一棵\(dfs\)树,先让子树处理完子树内部的边。子树可能无法恰好配对,当前可以处理的边就有子树内没能处理掉的边、与当前点相连的非树边、与父亲相连的边。尽量进行配对,如果无法完全配对就将剩下的那条边(必须是与父亲相连的那条)传回给父亲处理。

//@Author: wxyww
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
#include<ctime>
#include<cmath>
#include<map>
#include<string>
using namespace std;
typedef long long ll;
const int N = 2000000 + 10;
ll read() {
    ll x = 0,f = 1; char c = getchar();
    while(c < '0' || c > '9') {if(c == '-') f = -1;c = getchar();}
    while(c >= '0' && c <= '9') {x = x * 10 + c - '0',c = getchar();}
    return x * f;
}
int du[N];
struct node {
    int u,v,nxt,id,id2;
}e[N];
struct NODE {
    int u,v,id1,id2;
};
queue<NODE>q;
int head[N],ejs = 1;
void add(int u,int v,int id,int id2) {
    e[++ejs].v = v;e[ejs].u = u;e[ejs].nxt = head[u];head[u] = ejs;e[ejs].id = id;e[ejs].id2 = id2;
}
int viss[N],n,m,vis[N],dep[N];
int dfs(int u,int fa) {
    int now = 0;
    vis[u] = 1;
    for(int i = head[u];i;i = e[i].nxt) {
        if((i ^ 1) == fa) continue;
        int v = e[i].v;
        if(!vis[v]) {
            dep[v] = dep[u] + 1;
            int k = dfs(v,i);
            if(!k) {    viss[e[i].id] = 1;continue;}
            if(now) {
                q.push((NODE){e[k].v,e[now].v,e[k].id,e[now].id});
                now = 0;
            }
            else now = k;
        }
        else {
            if(dep[v] < dep[u]) continue;
            if(viss[e[i].id]) continue;
            if(now) {
                q.push((NODE){e[i].v,e[now].v,e[i].id,e[now].id});
                now = 0;
            }
            else now = i;
        }
        viss[e[i].id] = 1;
    }
    if(now) {
        q.push((NODE){e[fa ^ 1].v,e[now].v,e[fa].id,e[now].id});
        return 0;
    }
    return fa;
}
int vise[N],top,ans[N];
void Eur(int u) {
    for(int &i = head[u];i;i = e[i].nxt) {
        if(vise[i >> 1]) continue;
        vise[i >> 1] = 1;
        int v = e[i].v;
        int tmp = i;
        Eur(v);
        ans[++top] = e[tmp].id2;ans[++top] = e[tmp].id;
    }
}
int main() {
    n = read(),m = read();
    if(m & 1) return puts("0"),0;

    for(int i = 1;i <= m;++i) {
        int u = read(),v = read();
        du[u]++;du[v]++;
        add(u,v,i,0);add(v,u,i,0);
    }

    for(int i = 1;i <= n;++i) if(!(du[i] & 1)) return puts("0"),0;
    puts("1");

    dep[1] = 1;
    dfs(1,0);

    ejs = 1;memset(head,0,sizeof(head));

    while(!q.empty()) {
        NODE k = q.front();q.pop();
        add(k.u,k
首页 上一页 1 2 3 下一页 尾页 2/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇剑指offer50:数组中重复的数字 下一篇线性DP详解

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目