/* Topcoder SRM 705, D2 500-Pointer.
AlphabetOrderDiv2
James S. Plank
Fri Feb 3 16:23:38 EST 2017
*/
#include <string>
#include <vector>
#include <iostream>
#include <cstdio>
#include <cstdlib>
using namespace std;
class AlphabetOrderDiv2 {
public:
vector < vector <int> > Adj;
vector <int> Visited;
string isOrdered(vector <string> words);
int DFS(int n);
};
int AlphabetOrderDiv2::DFS(int n)
{
int i;
if (Visited[n] == 2) return 0; /* When visited == 2, we already know there's no cycle. */
if (Visited[n] == 1) return 1; /* However, if visited == 1, we've discovered a cycle. */
Visited[n] = 1;
/* Call DFS(i) on every node where there is an edge from n to i.
Return instantly if you've detected a cycle. */
for (i = 0; i < Adj[n].size(); i++) {
if (Adj[n][i]) {
if (DFS(i)) return 1;
}
}
/* If there's no cycle, you can set visited to 2, and return that there is no cycle. */
Visited[n] = 2;
return 0;
}
string AlphabetOrderDiv2::isOrdered(vector <string> words)
{
int i, j, c1, c2;
/* I'm using an adjacenty matrix. Set it so that all entries are zero. */
Adj.resize(26);
for (i = 0; i < Adj.size(); i++) Adj[i].resize(26, 0);
/* Now go through the words, and set edges in the adjacency matrix.
You should make sure that you don't set an edge from a node to itself. */
for (i = 0; i < words.size(); i++) {
for (j = 1; j < words[i].size(); j++) {
c1 = words[i][j-1] - 'a';
c2 = words[i][j] - 'a';
if (c1 != c2) Adj[c1][c2] = 1;
}
}
/* Print the adjacency matrix. */
printf(" ");
for (i = 'a'; i <= 'z'; i++) printf("%c", i);
printf("\n");
for (i = 0; i < Adj.size(); i++) {
printf("%c ", 'a'+i);
for (j = 0; j < Adj.size(); j++) printf("%d", Adj[i][j]);
printf("\n");
}
/* Set all Visited fields to zero, and do a DFS on every node.
If you discover a cycle, return "Impossible" */
Visited.resize(Adj.size(), 0);
for (i = 0; i < Adj.size(); i++) {
if (DFS(i)) return "Impossible";
}
/* If you haven't found any cycles, return "Possible" */
return "Possible";
}
|