zoukankan      html  css  js  c++  java
  • codeforces 1282 E. The Cake Is a Lie (dfs+构造)

    链接:https://codeforces.com/contest/1282/problem/E

    题意:给的是一张平面图,是一个n边形,每次可以切一刀,切出一个三角形,最终切成n-2个三角形。题目给出所切三角形的三个顶点的编号,以及三角形的编号。问你切出的三角形顺序,以及按顺序输出原始n边形顶点的所有编号,可以逆序输出也顺序输出。

    题解:有点类似拓扑排序。首先输入三角形三个点,a,b,c,统计出V[a] Xor b Xor c,同理统计V[b],V[c],这样可以保证V[i]的值只能是0 Xor 与i相连的两个点,即使三角形有共用边,多次Xor会消除公用边相连的点。根据这个性质,可以顺序输出所有点的编号。

             那么三角形顺序怎么输出呢?首先发现如果一条边是被两个三角形公用的,那么可以依据这条边把两个三角形相连,这样把三角形作为一个节点从而形成了一个图,这个图结构是一颗树,我们就随便找一个叶子节点,从叶子节点开始dfs遍历一遍,输出三角形编号即可。

    AC代码:

     1 #include<iostream>
     2 #include<vector>
     3 #include<cstring>
     4 #include<map>
     5 #include<algorithm>
     6 using namespace std;
     7 const int maxn = 1e+5;
     8 int v[maxn];
     9 vector<int> g[maxn];
    10 int visit[maxn];
    11 void dfs(int x){ //从叶子节点开始搜索,因为叶子节点必定代表着最靠外的三角形,它的度是1
    12     visit[x] = 1;
    13     for(int i = 0;i<g[x].size() ;i++){
    14         int cur = g[x][i];
    15         if(visit[cur] ==0) dfs(g[x][i]);
    16 //        dfs(g[x][i]);
    17     }
    18     cout<<x<<" ";
    19 }
    20 int main(){
    21     int t;cin>>t;
    22     while(t--){
    23         int n;
    24         cin>>n;
    25         for(int i = 0;i<=maxn;i++){
    26             v[i] = 0;//初始化V数组
    27             visit[i] = 0;//初始化访问数组
    28             g[i].clear() ;
    29         }
    30         map<pair<int,int>,vector<int> > mp;
    31         for(int i = 0;i<n-2;i++){
    32             int a,b,c;
    33             cin>>a>>b>>c;
    34             if(a>b) swap(a,b);
    35             if(b>c) swap(b,c);
    36             if(a>b) swap(a,b);
    37             v[a]^=b,v[a]^=c;//Xor操作
    38             v[b]^=a,v[b]^=c;
    39             v[c]^=a,v[c]^=b;
    40             mp[{a,b}].push_back(i+1);//添加一条边a,b,以及所共用的三角形i+1
    41             mp[{a,c}].push_back(i+1);
    42             mp[{b,c}].push_back(i+1);
    43         }
    44         int a,b;
    45         for(auto h:mp){
    46             if(h.second.size()==1){ //随便找一条边,只共用一个三角形
    47                 a = h.first.first;
    48                 b = h.first.second;
    49             //    break;
    50             }
    51         }
    52         cout<<a<<" "<<b;//输出这条边
    53         for(int i = 0;i<n-2;i++){
    54             int t = a^v[b];//开始做Xor操作。具体可以用笔模拟一下这个过程,理解更清楚
    55             cout<<" "<<t;
    56             a = b,b = t;
    57         }
    58         cout<<endl;
    59         for(auto h:mp){
    60             if(h.second.size() == 2){
    61                 int u = h.second[0],v = h.second[1];
    62                 g[u].push_back(v),g[v].push_back(u);//根据共用边以三角形为一个点建图
    63             }
    64         }
    65         dfs(1);
    66         cout<<endl;
    67     }
    68     return 0;
    69 }
  • 相关阅读:
    Smart Client Architecture and Design Guide
    Duwamish密码分析篇, Part 3
    庆贺发文100篇
    .Net Distributed Application Design Guide
    New Introduction to ASP.NET 2.0 Web Parts Framework
    SPS toplevel Site Collection Administrators and Owners
    来自Ingo Rammer先生的Email关于《Advanced .Net Remoting》
    The newsletter published by Ingo Rammer
    深度探索.Net Remoting基础架构
    信道、接收器、接收链和信道接受提供程序
  • 原文地址:https://www.cnblogs.com/AaronChang/p/12130172.html
Copyright © 2011-2022 走看看