您的位置:首页 > 其它

【BZOJ1706】[usaco2007 Nov]relays 奶牛接力跑【DP】【矩阵乘法】【限制最短路】

2016-03-15 15:24 489 查看
http://www.lydsy.com/JudgeOnline/problem.php?id=1706

论文题,详见《矩阵乘法在信息学中的应用》俞华程。

论文说点不会超过100,于是就开了100,果断RE,然后意识到编号最大会到1000,于是只能加个标号了。

inf开小了,wa了几发...

注意因为改了矩阵乘法定义,所以单位矩阵也不是平常的单位矩阵了(我觉得应该是全为inf),强行搞单位矩阵有点麻烦,所以手动先乘一次,指数减一,这样方便。

这是数据:http://contest.usaco.org/TESTDATA/NOV07_5.htm

/* Footprints In The Blood Soaked Snow */
#include <cstdio>
#include <algorithm>

using namespace std;

const int maxn = 105, inf = 0x3f3f3f3f, maxm = 1005;

int id[maxm], N;

struct _matrix {
int num[maxn][maxn];
} trans;

inline int iread() {
int f = 1, x = 0; char ch = getchar();
for(; ch < '0' || ch > '9'; ch = getchar()) f = ch == '-' ? -1 : 1;
for(; ch >= '0' && ch <= '9'; ch = getchar()) x = x * 10 + ch - '0';
return f * x;
}

inline int getid(int x) {
if(!id[x]) id[x] = ++N;
return id[x];
}

inline _matrix mul(_matrix &A, _matrix &B) {
_matrix C;
for(int i = 1; i <= N; i++) for(int j = 1; j <= N; j++) {
C.num[i][j] = inf;
for(int k = 1; k <= N; k++) C.num[i][j] = min(C.num[i][j], A.num[i][k] + B.num[k][j]);
}
return C;
}

inline _matrix qpow(_matrix &A, int n) {
_matrix ans = A; n--;
for(_matrix t = A; n; n >>= 1, t = mul(t, t)) if(n & 1) ans = mul(ans, t);
return ans;
}

int main() {
for(int i = 0; i < maxn; i++) for(int j = 0; j < maxn; j++) trans.num[i][j] = inf;

int n = iread(), m = iread(), st = iread(), ed = iread();
for(int i = 1; i <= m; i++) {
int w = iread(), a = iread(), b = iread(); a = getid(a); b = getid(b);
trans.num[a][b] = min(trans.num[a][b], w);
trans.num[b][a] = min(trans.num[b][a], w);
}

_matrix ans = qpow(trans, n);
printf("%d\n", ans.num[getid(st)][getid(ed)]);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息