zoukankan      html  css  js  c++  java
  • 某模拟题题解


      第一道题还是比较简单,只不过做的时候手贱写错了一个字母,然后活活RE掉了40分

      先处理处最终的图,然后从后往前用并查集完成询问。至于之前的删边可以排个序,

    然后建一个长度和它一样的boolean数组标志这条边又没被删,删除的时候就lower_bound

    就可以了,只不过注意重复的边。如果这一位上为false(这条边被删掉了)应该往后找到

    第一个为true的地方,然后将它改为false

    Code

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<fstream>
      4 #include<cstdlib>
      5 #include<queue>
      6 #include<set>
      7 #include<map>
      8 #include<cctype>
      9 #include<algorithm>
     10 #include<cstring>
     11 #include<string>
     12 #include<stack>
     13 using namespace std;
     14 typedef bool boolean;
     15 #define smin(a, b) a = min(a, b)
     16 #define smax(a, b) b = max(a, b)
     17 template<typename T>
     18 inline void readInteger(T& u) {
     19     char x;
     20     while(!isdigit(x = getchar()));
     21     for(u = x - '0'; isdigit((x = getchar())); u = (u << 3) + (u << 1) + x - '0');
     22     ungetc(x, stdin);
     23 }
     24 
     25 typedef class union_found{
     26     public:
     27         int *f;
     28         union_found():f(NULL) {}
     29         union_found(int points) {
     30             f = new int[(const int)(points + 1)];
     31             for(int i = 0; i <= points; i++)
     32                 f[i] = i;
     33         }
     34         int find(int x) {
     35             if(f[x] != x)    return f[x] = find(f[x]);
     36             return f[x];
     37         }
     38         void unit(int fa, int so) {
     39             int ffa = find(fa);
     40             int fso = find(so);
     41             f[fso] = ffa;
     42         }
     43         boolean connected(int a, int b) {
     44             return find(a) == find(b);
     45         }
     46 }union_found;
     47 
     48 typedef class _edge{
     49     public:
     50         int from;
     51         int end;
     52         _edge(const int a = 0, const int b = 0) {
     53             from = min(a, b);
     54             end = max(a, b);
     55         }
     56         boolean operator <(_edge another) const {
     57             if(this->from != another.from)    return this->from < another.from;
     58             return this->end < another.end;
     59         }
     60 }_edge;
     61 
     62 typedef class _question{
     63     public:
     64         boolean isCut;
     65         int a;
     66         int b;
     67 }_question;
     68 
     69 inline void readQues(_question& que){
     70     int c;
     71     readInteger(c);
     72     if(c == 1)    que.isCut = true;
     73     else que.isCut = false;
     74     readInteger(que.a);
     75     readInteger(que.b);
     76 }
     77 
     78 int n, m, q;
     79 union_found uf;
     80 _edge* es;
     81 boolean* enable;
     82 _question *ques;
     83 stack<int> s;
     84 
     85 #define MAP_IT multiset<_edge>::iterator
     86 
     87 inline void init() {
     88     int lastEdge;
     89     readInteger(n);
     90     readInteger(m);
     91     readInteger(q);
     92     es = new _edge[(const int)(m + 1)];
     93     uf = union_found(n);
     94     ques = new _question[(const int)(q + 1)];
     95     enable = new boolean[(const int)(m + 1)];
     96     lastEdge = m;
     97     memset(enable, true, sizeof(boolean) * (m + 1));
     98     for(int i = 1, a, b; i <= m; i++){
     99         readInteger(a);
    100         readInteger(b);
    101         es[i] = _edge(a, b);
    102     }
    103     sort(es + 1, es + m + 1);
    104     for(int i = 1; i <= q; i++){
    105         readQues(ques[i]);
    106         ques[i].a ^= lastEdge;
    107         ques[i].b ^= lastEdge;
    108         if(ques[i].isCut){
    109 //            es.erase(es.lower_bound(_edge(ques[i].a, ques[i].b)));
    110             int rank = lower_bound(es + 1, es + m + 1, _edge(ques[i].a, ques[i].b)) - es;
    111             while(!enable[rank]) rank++;
    112             enable[rank] = false;
    113             lastEdge--;
    114         }
    115     }
    116     for(int i = 1; i <= m; i++){
    117         if(enable[i])
    118             uf.unit(es[i].from, es[i].end);
    119     }
    120 }
    121 
    122 void solve() {
    123     for(int i = q; i > 0; i--){
    124         if(ques[i].isCut){
    125             uf.unit(ques[i].a, ques[i].b);
    126         }else{
    127             boolean result = uf.connected(ques[i].a, ques[i].b);
    128             if(result)    s.push(1);
    129             else s.push(0);
    130         }
    131     }
    132     while(!s.empty()){
    133         printf("%d
    ", s.top());
    134         s.pop();
    135     }
    136 }
    137 
    138 int main(){
    139     freopen("graph.in", "r", stdin);
    140     freopen("graph.out", "w", stdout);
    141     init();
    142     solve();
    143     fclose(stdin);
    144     fclose(stdout);
    145     return 0;
    146 }


      第二道相对于第一道题就没有那么友好了,这次真的只能用在线算法,于是我决定用暴力碰碰运气

    结果真的AC了。。。(这数据太水,没办法)

      思路很简单,这道题是树,所以,两点之间的连线断开后,就成了两个联通块,然后我给每个连通块

    一个编号,然后每次删边就去dfs一遍修改这个值。

    2018-2-17

      现在想了想,其实直接写一个LCT没多大毛病。

      记得标程用的树链剖分。于是考虑树链剖分怎么做。

      对于删边操作,如果删掉的是轻边,那么只需要更改father信息,如果删掉的是重边,那么需要修改重链上一段的重链顶,这个可以用线段树来维护。

      对于查询操作,两个点沿着重链一直往上跳,看最后跳到的点是否相同就可以判断联通了。

    Code

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<fstream>
      4 #include<cstdlib>
      5 #include<queue>
      6 #include<set>
      7 #include<map>
      8 #include<cctype>
      9 #include<algorithm>
     10 #include<cstring>
     11 #include<string>
     12 using namespace std;
     13 typedef bool boolean;
     14 #define smin(a, b) a = min(a, b)
     15 #define smax(a, b) b = max(a, b)
     16 template<typename T>
     17 inline void readInteger(T& u) {
     18     char x;
     19     while(!isdigit(x = getchar()));
     20     for(u = x - '0'; isdigit((x = getchar())); u = (u << 3) + (u << 1) + x - '0');
     21     ungetc(x, stdin);
     22 }
     23 
     24 ///Linked Map Template Starts
     25 typedef class Edge{
     26     public:
     27         int next;
     28         int end;
     29         Edge(const int next = 0, const int end = 0):next(next), end(end){    }
     30 }Edge;
     31 typedef class MapManager{
     32     public:
     33         int *h;
     34         Edge* edge;
     35         int ce;
     36         MapManager():h(NULL), edge(NULL), ce(0) { }
     37         MapManager(int point, int edges):ce(0){
     38             h = new int[(const int)(point + 1)];
     39             edge = new Edge[(const int)(edges + 1)];
     40             memset(h, 0, sizeof(int) * (point + 1));
     41         }
     42         inline void addEdge(int from, int end) {
     43             edge[++ce] = Edge(h[from], end);
     44             h[from] = ce;
     45         }
     46 }MapManager;
     47 ///Linked Map Template Ends
     48 
     49 int n, q;
     50 MapManager tree;
     51 int* fa;
     52 int* value;
     53 int* types;
     54 int ct;
     55 
     56 inline void init() {
     57     ct = 1;
     58     readInteger(n);
     59     readInteger(q);
     60     value = new int[(const int)(n + 1)];
     61     fa = new int[(const int)(n + 1)];
     62     tree = MapManager(n, 2 * n);
     63     types = new int[(const int)(n + 1)];
     64     fill(types + 1, types + n + 1, 1);
     65     for(int i = 1; i <= n; i++)    readInteger(value[i]);
     66     for(int i = 1, a, b; i < n; i++){
     67         readInteger(a);
     68         readInteger(b);
     69         tree.addEdge(a, b);
     70         tree.addEdge(b, a);
     71     }
     72 }
     73 
     74 void buildTree(int node, int lastNode){
     75     fa[node] = lastNode;
     76     for(int i = tree.h[node]; i != 0; i = tree.edge[i].next){
     77         int& end = tree.edge[i].end;
     78         if(end == lastNode)    continue;
     79         buildTree(end, node);
     80     }
     81 }
     82 
     83 void update(int node, int lastNode, const int newType){
     84     if(fa[node] != lastNode) return;
     85     types[node] = newType;
     86     for(int i = tree.h[node]; i != 0; i = tree.edge[i].next){
     87         int& end = tree.edge[i].end;
     88         if(end == lastNode)    continue;
     89         update(end, node, newType);
     90     }
     91 }
     92 
     93 int lastans;
     94 
     95 inline void solve() {
     96     buildTree(1, 0);
     97     for(int i = 1, c, a, b; i <= q; i++){
     98         readInteger(c);
     99         readInteger(a);
    100         readInteger(b);
    101         a ^= lastans;
    102         b ^= lastans;
    103         int s;
    104         switch(c){
    105         case 1:
    106             if(fa[a] == b){
    107                 s = a;
    108             }else{
    109                 s = b;
    110             }
    111             fa[s] = 0;
    112             update(s, 0, ++ct);
    113             break;
    114         case 2:
    115             if(types[a] == types[b]){
    116                 lastans = value[a] * value[b];
    117             } else {
    118                 lastans = value[a] + value[b];
    119             }
    120             printf("%d
    ", lastans);
    121             break;
    122         case 3:
    123             value[a] = b;
    124             break;
    125         default:
    126 //            throw c;
    127             break;
    128         }
    129     }
    130 }
    131 
    132 int main(){
    133     freopen("tree.in", "r", stdin);
    134     freopen("tree.out", "w", stdout);
    135     init();
    136     solve();
    137     return 0;
    138 }


      第三题,也是最简单的一道,直接Tarjan搜强连通分量不解释

    Code

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<fstream>
      4 #include<cstdlib>
      5 #include<queue>
      6 #include<set>
      7 #include<map>
      8 #include<stack>
      9 #include<cctype>
     10 #include<algorithm>
     11 #include<cstring>
     12 #include<string>
     13 using namespace std;
     14 typedef bool boolean;
     15 #define smin(a, b) a = min(a, b)
     16 #define smax(a, b) b = max(a, b)
     17 template<typename T>
     18 inline void readInteger(T& u) {
     19     char x;
     20     while(!isdigit(x = getchar()));
     21     for(u = x - '0'; isdigit((x = getchar())); u = (u << 3) + (u << 1) + x - '0');
     22     ungetc(x, stdin);
     23 }
     24 ///Linked Map Template Starts
     25 typedef class Edge{
     26     public:
     27         int next;
     28         int end;
     29         Edge(const int next = 0, const int end = 0):next(next), end(end){    }
     30 }Edge;
     31 typedef class MapManager{
     32     public:
     33         int *h;
     34         Edge* edge;
     35         int ce;
     36         MapManager():h(NULL), edge(NULL), ce(0) { }
     37         MapManager(int point, int edges):ce(0){
     38             h = new int[(const int)(point + 1)];
     39             edge = new Edge[(const int)(edges + 1)];
     40             memset(h, 0, sizeof(int) * (point + 1));
     41         }
     42         inline void addEdge(int from, int end) {
     43             edge[++ce] = Edge(h[from], end);
     44             h[from] = ce;
     45         }
     46 }MapManager;
     47 ///Linked Map Template Ends
     48 
     49 MapManager g;
     50 long long result;
     51 
     52 stack<int> s;
     53 boolean* visited;
     54 boolean* inStack;
     55 int counter;
     56 int *visitID;
     57 int *exitID;
     58 
     59 inline void getMap(int end){
     60     int c_m = 0;
     61     int node;
     62     do{
     63         node = s.top();
     64         s.pop();
     65         inStack[node] = false;
     66         c_m++;
     67     }while(node != end);
     68     result += c_m * 1LL * (c_m - 1) / 2;
     69 }
     70 
     71 void Tarjan(int node){
     72     visited[node] = true;
     73     visitID[node] = exitID[node] = ++counter;
     74     s.push(node);
     75     inStack[node] = true;
     76     for(int i = g.h[node]; i != 0; i = g.edge[i].next){
     77         int e = g.edge[i].end;
     78         if(!visited[e]) {
     79             Tarjan(e);
     80             smin(exitID[node], exitID[e]);
     81         } else if(inStack[e]) {
     82             smin(exitID[node], visitID[e]);
     83         }
     84     }
     85     if(visitID[node] == exitID[node])
     86         getMap(node);
     87 }
     88 
     89 int n;
     90 int m;
     91 
     92 inline void init() {
     93     readInteger(n);
     94     readInteger(m);
     95     g = MapManager(n, m);
     96     visited = new boolean[(const int)(n + 1)];
     97     inStack = new boolean[(const int)(n + 1)];
     98     visitID = new int[(const int)(n + 1)];
     99     exitID = new int[(const int)(n + 1)];
    100     memset(visited, false, sizeof(boolean) * (n + 1));
    101     memset(inStack, false, sizeof(boolean) * (n + 1));
    102     for(int i = 1, a, b; i <= m; i++) {
    103         readInteger(a);
    104         readInteger(b);
    105         g.addEdge(a, b);
    106     }
    107 }
    108 
    109 inline void solve() {
    110     for(int i = 1; i <= n; i++) {
    111         if(!visited[i])
    112             Tarjan(i);
    113     }
    114     cout<<result;
    115 }
    116 
    117 int main(){
    118     freopen("logic.in", "r", stdin);
    119     freopen("logic.out", "w", stdout);
    120     init();
    121     solve();
    122     return 0;
    123
  • 相关阅读:
    微信公众号迁移配置注意点
    关于memcache 命令查看和 Telnet
    centOS 安装(光安装 和 u盘安装)
    CentOS删除自带的java,安装新java
    ubuntu常用命令
    ubuntu 的挂起与休眠
    saiku应用的调试
    数据挖掘123
    unbutu 安装java教程
    workbench的schema讲解一:(维度dimension设置的基本内容)
  • 原文地址:https://www.cnblogs.com/yyf0309/p/5933800.html
Copyright © 2011-2022 走看看