题意分析:
Santa要画一只刺猬,现在有n个点,m条边。刺猬的定义是有尾巴和刺。尾巴:从尾巴的起始端到末尾,所有的标号都严格递增,eg.1->2->4这样子。然后画刺,刺的画法是在画完尾巴之后,将所有的边都染色,此时选定一个结点为尾巴末尾,这个末尾上的所有边,都是刺。刺猬的优美度 = 尾巴长度(尾巴上点的个数) X 刺个数。问:最大的优美度是多少?
解题思路:
尾巴单调递增,而刺只是这个点周围的边个数。所以可以设dp[i]为到点i为止,最长的尾巴长度。然后更新ans = max(ans, dp[i] * G[i].size())即可。
个人感受:
昨天写了dfs,T35。然后今天去优化半天,死活T60,看了样例感觉并不会T,估计是STL的锅。然后用DP就秒过了= =。
具体代码如下:
先上DP代码:
#include<algorithm> #include<cctype> #include<cmath> #include<cstdio> #include<cstring> #include<iomanip> #include<iostream> #include<map> #include<queue> #include<set> #include<sstream> #include<stack> #include<string> #define ll long long using namespace std; const int MAXN = 1e5 + 111; vector<int> G[MAXN]; ll dp[MAXN]; int n, m; ll ans = 0; int main() { int u, v; scanf("%d%d", &n, &m); for (int i = 0; i < m; ++i) { scanf("%d%d", &u, &v); G[u].push_back(v); G[v].push_back(u); } for (int i = 1; i <= n; ++i) { dp[i] = 1; for (int j = 0; j < G[i].size(); ++j) { if (G[i][j] < i) { dp[i] = max(dp[i], dp[G[i][j]] + 1); } } ans = max(ans, G[i].size() * dp[i]); } printf("%I64d\n", ans); return 0; }
然后是T的搜索代码:
#include<algorithm> #include<cctype> #include<cmath> #include<cstdio> #include<cstring> #include<iomanip> #include<iostream> #include<map> #include<queue> #include<set> #include<sstream> #include<stack> #include<string> #define lowbit(x) (x & (-x)) #define root 1, n, 1 #define lson l, m, rt << 1 #define rson m + 1, r, rt << 1 1 #define ll long long #define pr(x) cout << #x << " = " << (x) << '\n'; using namespace std; const int INF = 0x7f7f7f7f; const int MAXN = 1e5 + 111; set<int> G[MAXN]; int vis[MAXN]; int n, m; ll ans = 0; void dfs(int u, ll len) { vis[u] = len; for (set<int>::iterator it = G[u].begin(); it != G[u].end(); ++it) { int v = *it; if (v > u && len + 1 > vis[v]) { dfs(v, len + 1); } } ans = max(ans, len * G[u].size()); } int main() { int u, v; scanf("%d%d", &n, &m); for (int i = 0; i < m; ++i) { scanf("%d%d", &u, &v); G[u].insert(v); G[v].insert(u); } for (int i = 1; i <= n; ++i) { if (!vis[i]) { dfs(i, 1); } } printf("%I64d\n", ans); return 0; }