标签:acm
此类题目有一个明显的特点,是n个点或者n*n的矩阵,否则无法做矩阵运算
点数不能太大,因为矩阵操作的复杂度是O(N^3)的,所以大概最多只能有100个点
给一个n*n的矩阵a,保证a[i][i]>0,所有元素非负
若干次幂之后,问时候能保证矩阵中不含有零
首先说明一点,矩阵的数值是没有多少关系的,只有零和大于零的数有区别,不妨把大于零的数变成1。对于a*a,可以考虑到,如果求出来a[i][j]大于零,那么相当于i通过一个点可以到达j,那么a^k就可以理解为经过k个点,所有点能不能互相到达。矩阵保证了对角线均大于零,也就是说点i可以通过点i到达i,所以最后的结果就是求一下所有点是不是能互相到达即可(i如果能经过k个点到达j,那么经过大于k个点也能到达j)
所以,问题转化成求整个图的连通性
const int MAXN = 2100; bitset<MAXN> ipt[MAXN]; int main() { // freopen("in.txt", "r", stdin); int n; while (~RI(n)) { REP(i, n) REP(j, n) { int t; RI(t); ipt[i][j] = !!t; } bool ok = true; REP(k, n) REP(i, n) if (ipt[i][k]) ipt[i] |= ipt[k]; REP(i, n) REP(j, n) if (ipt[i][j] == 0) ok = false; if (ok) puts("YES"); else puts("NO"); } return 0; }
const int MAXN = 2100; vector<int> G[MAXN], RG[MAXN]; bool vis[MAXN], rvis[MAXN]; void dfs(int u) { vis[u] = true; REP(i, G[u].size()) { int v = G[u][i]; if (!vis[v]) dfs(v); } } void rdfs(int u) { rvis[u] = true; REP(i, RG[u].size()) { int v = RG[u][i]; if (!rvis[v]) rdfs(v); } } int main() { // freopen("in.txt", "r", stdin); int n; while (~RI(n)) { CLR(vis, false); CLR(rvis, false); REP(i, n) { G[i].clear(); RG[i].clear(); } REP(i, n) REP(j, n) { int t; RI(t); if (t) { G[i].push_back(j); RG[j].push_back(i); } } dfs(0); rdfs(0); bool ok = true; REP(i, n) if (!vis[i]) ok = false; REP(i, n) if (!rvis[i]) ok = false; if (ok) puts("YES"); else puts("NO"); } return 0; }
const LL INF = 1e18; const int MAXN = 60; struct Matric { LL a[MAXN][MAXN]; int n; } ipt; Matric operator* (Matric x, Matric y) { Matric ret; ret.n = x.n; REP(i, x.n) REP(j, x.n) ret.a[i][j] = INF; REP(i, x.n) REP(j, x.n) REP(k, x.n) ret.a[i][j] = min(ret.a[i][j], x.a[i][k] + y.a[k][j]); return ret; } Matric pow(Matric a, int b) { Matric ret; ret.n = a.n; bool flag = false; while (b) { if (b & 1) { if (flag) ret = ret * a; else ret = a; flag = true; } a = a * a; b >>= 1; } return ret; } int main() { // freopen("in.txt", "r", stdin); int T, v, e, k, a, b, d; RI(T); REP(kase, T) { RIII(v, e, k); ipt.n = v; REP(i, v) REP(j, v) ipt.a[i][j] = INF; REP(i, e) { RIII(a, b, d); a--; b--; ipt.a[a][b] = min(ipt.a[a][b], (LL)d); } ipt = pow(ipt, k); if (ipt.a[0][v - 1] != INF) cout << ipt.a[0][v - 1] << endl; else puts("-1"); } return 0; }
标签:acm
原文地址:http://blog.csdn.net/wty__/article/details/24709425