【I'm Telling the Truth】【HDU - 3729】 【匈牙利演算法,DFS】
阿新 • • 發佈:2019-08-18
思路
題意:該題主要說幾個同學分別說出自己的名次所處區間,最後輸出可能存在的未說謊的人數及對應的學生編號,而且要求字典序最大。
思路:剛剛接觸匈牙利演算法,瞭解的還不太清楚,附一個專門講解匈牙利演算法的博文,個人認為講的比較清晰。
AC程式碼
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int T, n;
struct Stue
{
int l, r;
};
Stue per[60+10];
int vis[100000+10]; //判斷該點是否訪問過
int hon[60+10]; //用於記錄未說謊的人的編號
int ok[100000+10]; //標記某點存在的學生編號,未有則預設為-1
bool dfs(int x)
{
if(x < 0)
return false;
for(int i = per[x].l; i <= per[x].r; i++)
{
if(!vis[i])
{
vis[i] = 1;
if(ok[i] == -1 || dfs(ok[i]))
{
ok[i] = x;
return true;
}
}
}
return false;
}
int main()
{
// freopen("input.txt", "r", stdin);
// freopen("output.txt", "w", stdout);
cin >> T;
while(T--)
{
cin >> n;
for(int i = 0; i < n; i++)
cin >> per[i].l >> per[i].r;
int cnt = 0;
memset(hon, 0, sizeof(hon));
memset(ok, -1, sizeof(ok));
for(int i = n - 1; i >= 0; i--) //從後往前,這樣可以保證字典序最大
{
memset(vis, 0, sizeof(vis));
if(dfs(i))
hon[cnt++] = i;
}
cout << cnt << endl;
if(!cnt)
continue;
for(int i = cnt - 1; i > 0; i--)
cout << hon[i] + 1 << " ";
cout << hon[0] + 1 << endl;
}
}