USACO 5.4 Character Recognition

很像多年前做过的某道双调路径的题,记得当时实在vijos上面做的。。

不说了,比较简单的dp,dp[i][j]表示从节点1出发一条路径到达i,另一条路径到达j时经过的节点数的最大值。显然这个dp矩阵是对称的,dp[i][j]==dp[j][i],所以计算量可以只算矩阵的一半。而结果就是max(dp[i][n]),其中从i到n有直接路径。

还有一种做法,在nocow上面看得,是求最大费用流的解法,也挺不错的。。当时我没想到= =,网络流的建模博大精深啊。。

 

/*
ID: zlqest11
LANG: C++
TASK: tour
*/
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
using namespace std;

const int N = 105;

int n, m, dp[N][N];
string name[N];
bool map[N][N];

int getId(const char *s){
string str = s;
for(int i = 1; i <= n; i++)
if(str == name[i])
return i;
printf("ERROR\n");
return -1;
}

int main()
{
char astr[20], bstr[20];
int a, b;
freopen("tour.in", "r", stdin);
freopen("tour.out", "w", stdout);
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; i++) cin >> name[i];
memset(map, false, sizeof(map));
for(int i = 0; i < m; i++){
scanf("%s %s", astr, bstr);
a = getId(astr);
b = getId(bstr);
map[a][b] = map[b][a] = true;
}
memset(dp, -1, sizeof(dp));
dp[1][1] = 1;
for(int i = 1; i <= n; i++)
for(int j = i+1; j <= n; j++){
for(int k = 1; k < j; k++)
if(map[j][k] && dp[i][k]>0)
dp[i][j] = dp[j][i] = max(dp[i][j], dp[i][k]+1);
}
int ans = 1;
for(int i = 1; i < n; i++)
if(map[i][n])
ans = max(ans, dp[i][n]);
printf("%d\n", ans);
return 0;
}



你可能感兴趣的:(character)