思路:求最大可能的说真话的人数,也就是匹配数,因为一个人说的是真话的前提是可以找到正确的理论支撑点,也就是在他所说的话中,l <= x <= r,至少存在一种关系是真的,也就是对于m属于[l,r] && m != x,使得真的有x < m || x > m,这个也就是匹配关系;
/***************************************** Author :Crazy_AC(JamesQi) Time :2015 File Name : *****************************************/ // #pragma comment(linker, "/STACK:1024000000,1024000000") #include <iostream> #include <algorithm> #include <iomanip> #include <sstream> #include <string> #include <stack> #include <queue> #include <deque> #include <vector> #include <map> #include <set> #include <stdio.h> #include <string.h> #include <math.h> #include <stdlib.h> #include <limits.h> using namespace std; #define MEM(a,b) memset(a,b,sizeof a) #define pk push_back template<class T> inline T Get_Max(const T&a,const T&b){return a < b?b:a;} template<class T> inline T Get_Min(const T&a,const T&b){return a < b?a:b;} typedef long long ll; typedef pair<int,int> ii; const int inf = 1 << 30; const int INF = 0x3f3f3f3f; const int MOD = 1e9 + 7; int uN,vN; const int maxn = 6e6 + 10; int head[100010]; struct Edge{ int to,nxt; }E[maxn]; int tol; int n; vector<int> vec; void addedge(int u,int v){ E[tol].to = v; E[tol].nxt = head[u]; head[u] = tol++; } int mark[100010],link[100010]; bool Search_P(int u){ for (int i = head[u];i != -1;i = E[i].nxt){ int v = E[i].to; if (!mark[v]){ mark[v] = 1; if (link[v] == -1 || Search_P(link[v])){ link[v] = u; return true; } } } return false; } inline int Hungary(){ int ret = 0; MEM(link, -1); for (int i = n - 1;i >= 0;i--){ MEM(mark, 0); if (Search_P(i)){ ret++; vec.push_back(i); } } return ret; } int main() { // ios::sync_with_stdio(false); // freopen("in.txt","r",stdin); // freopen("out.txt","w",stdout); int T; cin >> T; while(T--){ scanf("%d",&n); int a,b; MEM(head, -1); tol = 0; for (int i = 0;i < n;i++){ scanf("%d%d",&a,&b); for (int j = a;j <= b;++j) addedge(i,j); } vec.clear(); // int ans; printf("%d\n",Hungary()); sort(vec.begin(),vec.end()); for (int i = 0;i < vec.size();i++){ printf("%d%c",vec[i] + 1,(i == vec.size() - 1)?'\n':' '); } } return 0; }