Andrew Stankevich's Contest #2
Solution
Problem A: NonAbsorbing DFA
Problem B: TheTowers of Hanoi Revisited
Problem C:Hyperhuffman
Problem D: LittleJumper
Problem E:Quantization Problem
Problem F: Roads
Problem G:Robbers
Problem H: ToralTickets
July 30th,2013 by chlxyd,xioumu
Problem A:Non Absorbing DFA
给一个编译原理中的DFA图,图有一个起点,多个终点,图的边表示为一个F矩阵,f[i][j]表示i点用字母j可以连向f[i][j]点。还给了一个G,对于G[i][j] = 1表示,i点用字母j连出去的边时空边(也就是不会消耗字母j).
求有多少不同的长度为N的字符串符合这个DFA图(可以重起点走到终点)
Solution
Tag:图论,DP
若没有空边的话,直接用个简单的Dp就可以求出答案了,所以现在只要处理掉空边就行了。
若G(I,j)空边组成了一个环,那么到I节点的字母j永远不会走出环。所以若存在环,直接把环上的边都删了就行。
若G(i,j)没有组成环,那么直接把的G(I,j)指向这条路径上第一条非空边指向的点即可。
/*
* Author: chlxyd
* Created Time: 2013/7/20 14:36:12
* File Name: A.cpp
*/
#include<iostream>
#include<sstream>
#include<fstream>
#include<vector>
#include<list>
#include<deque>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<bitset>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cctype>
#include<cmath>
#include<ctime>
using namespace std;
const double eps(1e-8);
typedef long long lint;
#define clr(x) memset( x , 0 , sizeof(x) )
#define sz(v) ((int)(v).size())
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define repf(i, a, b) for (int i = (a); i <= (b); ++i)
#define repd(i, a, b) for (int i = (a); i >= (b); --i)
#define clrs( x , y ) memset( x , y , sizeof(x) )
const int maxn = 1000 + 10;
int vs[maxn], vt[maxn], v[maxn];
int n, m, len, S, tn;
char word[maxn];
vector<int> e[maxn], wo[maxn], g[maxn];
void add(vector<int> *e, vector<int> *wo, int x, int y, int w) {
e[x].push_back(y);
wo[x].push_back(w);
}
void add2(int x, int y) {
g[x].push_back(y);
}
void init() {
scanf("%s", word);
m = strlen(word);
scanf("%d", &n);
scanf("%d%d", &S, &tn);
clr(vs);
clr(vt);
S--;
vs[S] = 1;
rep (i, tn) {
int x;
scanf("%d", &x);
x--;
vt[x] = 1;
}
rep (i, n) {
e[i].clear();
g[i].clear();
wo[i].clear();
}
//printf("%d %d\n", n, m);
rep (i, n)
rep (j, m) {
int x;
scanf("%d", &x);
x--;
add(e, wo, i, x, j);
}
rep (i, n)
rep (j, m) {
int x;
scanf("%d", &x);
add2(i, x);
}
scanf("%d", &len);
//printf("%d\n", len);
}
int dfs(int x, int w) {
if (v[x]) return -1;
v[x] = 1;
rep (i, sz(e[x])) {
if (w == wo[x][i]) {
int j = e[x][i];
if (g[x][i]){
int h = dfs(j, w);
if (h == -1)
return -1;
e[x][i] = h;
g[x][i] = 0;
return h;
}
else if (!g[x][i]) {
return j;
}
}
}
return -1;
}
void getG2() {
rep (i, n) {
rep (k, sz(e[i])) {
if (g[i][k]) {
memset(v, 0, sizeof(v));
dfs(i, wo[i][k]);
}
}
}
}
void add(vector<int> &a, vector<int> b) {
int an = sz(a), bn = sz(b);
rep (i, min(an, bn)) {
a[i] += b[i];
}
repf (i, an, bn - 1) {
a.push_back(b[i]);
}
rep (i, max(an, bn)) {
if (a[i] >= 10) {
if (i + 1 >= sz(a))
a.push_back(0);
a[i + 1] += a[i] / 10;
a[i] %= 10;
}
}
}
void myset(vector<int> &a, int w) {
a.clear();
a.push_back(w);
}
void myput(vector<int> &a) {
repd (i, sz(a) - 1, 0) {
printf("%d", a[i]);
}
puts("");
}
vector<int> f[70][maxn];
//int f[70][maxn];
void ga