码迷,mamicode.com
首页 > 其他好文 > 详细

uestc 方老师的分身IV

时间:2015-02-25 22:23:57      阅读:179      评论:0      收藏:0      [点我收藏+]

标签:

类似POJ1386,参考的大神的博客

首先明确思路:

是否为连通图(并查集解决) -> 是否存在欧拉路径  ->  是否存在欧拉回路   (是,则选取字典序最小的输出,否则直接输出可行解)

 

注意区分有向图和无线图存在欧拉路径或者欧拉回路的条件:

无向图: G为连通图,并且G仅有两个奇度节点或者无奇度节点

  推论:1.当G是仅有两个奇度节点的连通图时,G的欧拉通路必以此两个结点为端点

     2.当G时无奇度结点的连通图时,G必有欧拉回路

     3.G为欧拉图(存在欧拉回路)的充分必要条件是G为无奇度节点的连通图

有向图:D为有向图,D的基图连通,并且所有顶点的出度与入度相等;或者除两个定点外,其余顶点的出度和入度都相等,而这两个顶点中一个顶点的出度与入度之差为1,另一个顶点的出度与入度之差为1

  推论:1.当D除出、入度之差为1,-1的两个顶点之外,其余顶点的出度与入度都相等时,D的有向欧拉通路必以出入度之差为1的顶点作为始点,以出入度之差为-1的顶点作为终点

     2.当D的所有顶点的出入度都相等时,D中存在有向欧拉回路

     3.有向图D为有向欧拉回路的充分必要条件是D的基图为连通图,并且所有顶点的出入度都相等

 

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstdlib>
  4 #include<cstring>
  5 #include<string>
  6 #include<queue>
  7 #include<algorithm>
  8 #include<map>
  9 #include<iomanip>
 10 #include<climits>
 11 #include<string.h>
 12 #include<cmath>
 13 #include<stdlib.h>
 14 #include<vector>
 15 #include<stack>
 16 #define INF 1000000007
 17 #define MAXN 40010
 18 #define Mod 1000007
 19 #define N 2010
 20 #define NN 30
 21 #define sigma_size 3
 22 const int maxn = 6e5 + 10;
 23 using namespace std;
 24 typedef long long LL;
 25 
 26 struct node{
 27     int u, v, next;
 28     string w;
 29 }G[N];
 30 
 31 int head[NN], fa[NN], ind[NN], outd[NN], vis[NN];
 32 int t, cnt, start, k;
 33 int evis[N];
 34 string ss[N];
 35 string ans[N];
 36 int T, n;
 37 
 38 bool cmp(string a, string b)
 39 {
 40     return a > b;
 41 }
 42 
 43 int findset(int x)
 44 {
 45     if (fa[x] == x) return x;
 46     return fa[x] = findset(fa[x]);
 47 }
 48 
 49 void merg(int a, int b)
 50 {
 51     int x = findset(a);
 52     int y = findset(b);
 53     if (y != x) {
 54         fa[x] = y;
 55     }
 56 }
 57 
 58 void addedge(int u, int v, string w)
 59 {
 60     G[t].u = u;
 61     G[t].v = v;
 62     G[t].w = w;
 63     G[t].next = head[u];
 64     head[u] = t++;
 65     outd[u]++;
 66     ind[v]++;
 67     vis[u] = vis[v] = 1;
 68     merg(u, v);
 69 }
 70 
 71 void read()
 72 {
 73     cin >> n;
 74     for (int i = 1; i <= n; ++i)
 75         cin >> ss[i];
 76     sort(ss + 1, ss + n + 1, cmp);
 77     for (int i = 1; i <= n; ++i) {
 78         int u = ss[i][0] - a;
 79         int v = ss[i][ss[i].length() - 1] - a;
 80         addedge(u, v, ss[i]);
 81     }
 82 }
 83 
 84 void init()
 85 {
 86     t = 1;
 87     for (int i = 0; i < 30; ++i)
 88         fa[i] = i;
 89     memset(ind, 0, sizeof(ind));
 90     memset(outd, 0, sizeof(outd));
 91     for (int i = 0; i <= 2000; i++)
 92     {
 93         G[i].u = G[i].v = G[i].next = 0;
 94         G[i].w = "";
 95     }
 96     memset(head, -1, sizeof(head));
 97     memset(evis, 0, sizeof(evis));
 98     memset(vis, 0, sizeof(vis));
 99     for (int i = 0; i < 2010; ++i)
100         ans[i] = "";
101 }
102 
103 bool Euler_Path()
104 {
105     int one = 0;
106     int none = 0;
107     int tot = 0;
108     start = -1;
109     for (int i = 0; i < 26; ++i) {
110         if (vis[i] == 0) continue;
111         //int tmp = findset(i);
112         if (findset(i) == i) tot++;
113         //cout << tot << endl;
114         if (ind[i] == outd[i] + 1) none++;
115         else if (ind[i] + 1 == outd[i]) {
116             one++;
117             start = i;
118         }
119         else if (ind[i] != outd[i])
120             return false;
121     }
122     if (tot != 1) return false;
123     if ((one == none && one == 1) || (one == none && one == 0)) {
124         if (start == -1) {
125             for (int i = 0; i < 26; ++i) {
126                 if (vis[i] && outd[i] > 0) {
127                     start = i;
128                     return true;
129                 }
130             }
131         }
132         if (one == none && one == 1) return true;
133         return false;
134     }
135     return false;
136 }
137 
138 
139 void dfs(int v, int flag)
140 {
141     for (int i = head[v]; i != -1; i = G[i].next) {
142         if (!evis[i]){
143             evis[i] = 1;
144             dfs(G[i].v, i);
145         }
146     }
147     if (flag != -1)
148         ans[cnt++] = G[flag].w;
149 }
150 void process()
151 {
152     init();
153     read();
154     if (Euler_Path()) {
155         cnt = 0;
156         dfs(start, -1);
157         for (int i = cnt - 1; i >= 0; --i) {
158             cout << ans[i];
159             if (i != 0) cout << ".";
160             else cout << endl;
161         }
162     }
163     else puts("***");
164 }
165 
166 int main()
167 {
168     cin >> T;
169     while (T--) {
170         process();
171     }
172     //system("pause");
173     return 0;
174 }

 

uestc 方老师的分身IV

标签:

原文地址:http://www.cnblogs.com/usedrosee/p/4300314.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!