题意:每个学生会回答有一个分数区间,问有多少个学生说慌了。而且输出字典序最大的解。
吐槽:我就是暴力建图的,左60,右10000….
技巧:要是边是一个区间的值,可以不用直接建边,在match()里面直接判断就ok了,省时间声内存呢。
900多ms
/************************************************ Author :DarkTong Created Time :2016/8/1 15:34:41 File Name :Hdu_3279.cpp *************************************************/ //#include <bits/stdc++.h> #include <cstring> #include <cstdio> #include <cmath> #include <algorithm> using namespace std; const int maxn = 60 + 10; const int maxs = 100000 + 10; #define INF 0x3f3f3f3f int w[maxn][maxs], n, m; int Left[maxs]; bool used[maxs]; int mi, ma; bool match(int i) { for(int j=mi;j<=ma;++j) if(w[i][j]&&!used[j]) { used[j] = true; if(!Left[j]||match(Left[j])) { Left[j] = i; return true; } } return false; } //返回最大匹配数 int hungary() { int res=0; memset(Left, 0, sizeof(Left)); for(int i=n;i>=1;--i) { memset(used, 0, sizeof(used)); if(match(i)) res++; } return res; } int main() { int T, cas=1; scanf("%d", &T); while(T--) { memset(w, 0, sizeof(w)); ma = 0, mi = INF; scanf("%d", &n); int u, v; for(int i=1;i<=n;++i) { scanf("%d%d", &u, &v); mi = min(mi, u); ma = max(ma, v); for(int j=u;j<=v;++j) { w[i][j]=1; } } int rec[100], nr=0, ans; ans = hungary(); for(int i=mi;i<=ma;++i) { if(Left[i]) rec[nr++]=Left[i]; } sort(rec, rec+nr); printf("%d\n", ans); for(int i=0;i<nr;++i) { printf("%d%c", rec[i], i==nr-1?'\n':' '); } } return 0; }
当然我怎么能让自己的代码跑那么久呢,所以改进了一下,没有直接连边,就判断一下。
100ms内
/************************************************ Author :DarkTong Created Time :2016/8/1 15:34:41 File Name :Hdu_3279.cpp *************************************************/ //#include <bits/stdc++.h> #include <cstring> #include <cstdio> #include <cmath> #include <algorithm> using namespace std; const int maxn = 60 + 11; const int maxs = 100000 + 10; #define INF 0x3f3f3f3f int n, m; int Left[maxs], peo[maxn][2]; bool used[maxs]; bool match(int i) { for(int j=peo[i][0];j<=peo[i][1];++j) if(!used[j]) { used[j] = true; if(!Left[j]||match(Left[j])) { Left[j] = i; return true; } } return false; } //返回最大匹配数 int hungary() { int res=0; memset(Left, 0, sizeof(Left)); for(int i=n;i>=1;--i) { memset(used, 0, sizeof(used)); if(match(i)) res++; } return res; } int main() { int T, cas=1; scanf("%d", &T); while(T--) { scanf("%d", &n); int u, v; for(int i=1;i<=n;++i) { scanf("%d%d", &peo[i][0], &peo[i][1]); } int rec[100], nr=0, ans; ans = hungary(); for(int i=0;i<maxs;++i) { if(Left[i]) rec[nr++]=Left[i]; } sort(rec, rec+nr); printf("%d\n", ans); for(int i=0;i<nr;++i) { printf("%d%c", rec[i], i==nr-1?'\n':' '); } } return 0; }
转载于:https://www.cnblogs.com/DarkTong/p/5726185.html