T城市有N個地鐵站,但它們不是兩兩之間都有地鐵經過的,有一些地鐵站之間存在一條單向的地鐵通道。
現在,Ryan需要爲T城市的地鐵站做一個大改造,由於羣衆抱怨,一些地鐵站的出發車次和到達車次的數目差距太大,導致地鐵站建設混亂。同時,Ryan也接到上級命令,暫時不修建新線路,只拆除,並且至少保留K條原有線路,在這個前提下,他希望儘量滿足羣衆需求,使得所有地鐵站出發車次和到達車次的最大差距最小,能保持差距在多少以內呢?
Input
輸入第一行爲T,表示有T組測試數據。
每組數據以三個整數,N,M,K開始。N表示地鐵站的數目,M表示原有的地鐵線路總數,K表示至少保留線路數目。接着M行,每行有兩個整數 Ai, Bi,表示一條單向地鐵線路。
[Technical Specification]
1. 1 <= T <= 88
2. 1 <= N <= 50
3. 0 <= K <= M <= N * (N – 1)
4. 1 <= Ai, Bi <= N, Ai != Bi, 每條線路最多出現一次
Output
對每組數據,先輸出爲第幾組數據,然後輸出最大差距。
Sample Input
3
2 1 1
1 2
2 1 0
1 2
4 4 3
1 2
1 3
2 4
4 3
Sample Output
Case 1: 1
Case 2: 0
Case 3: 1
Hint
在樣例3中,可以拆除第二條線路<1, 3>,那麼四個地鐵站的出發車次和到達車次差距分別爲1、0、1、0,最大爲1,是一種最優選擇。
解題:總共可以刪除M-K條路線,將整個地鐵路線圖當做一個有向圖,那麼就是刪除M-K條有向邊。
每刪除一條邊時,就先找當前入度和出度之差絕對值最大的點v,
如果v的入度大於出度,從指向v的結點集中選出一個(出度-入度)最大的結點u,刪除邊(u,v)
如果v的出度大於入度,從v指向的結點集中選出一個(入度-出度)最大的結點u,刪除邊(v,u)
每刪除一條邊時,就先找當前入度和出度之差絕對值最大的點v,
如果v的入度大於出度,從指向v的結點集中選出一個(出度-入度)最大的結點u,刪除邊(u,v)
如果v的出度大於入度,從v指向的結點集中選出一個(入度-出度)最大的結點u,刪除邊(v,u)
源碼:
#include <iostream>
#include <vector>
#include <utility>
#include <cmath>
using namespace std;
int Max_diff(vector<int>& degsIn, vector<int>& degsOut)
{
int size = degsIn.size();
int max = 0, res = 0;
for(int i = 0; i < size; ++i)
{
int temp = (int)abs((double)degsIn[i] - (double)degsOut[i]);
if(max < temp)
{
max = temp;
res = i;
}
}
return res;
}
int Sec_diff(vector<int>& nodes, vector<int>& degsIn, vector<int>& degsOut, int flag)
{
int max = -1000024, pos ;
for(int i = 0; i < nodes.size(); ++i)
{
if(nodes[i] < 0)
continue;
int temp = degsIn[nodes[i]] - degsOut[nodes[i]];
if( flag )
{
temp = -temp;
}
if( max < temp)
{
max = temp;
pos = i;
}
}
return nodes[pos];
}
void Del_nodes(vector<int>& nodes, int v)
{
for(int i = 0; i < nodes.size(); ++i)
if(nodes[i] == v)
{
nodes[i] = -1;
return ;
}
}
int main()
{
int T;
cin >> T;
for(int iCase = 1; iCase <= T; ++iCase)
{
int n, m, k;
cin >> n >> m >> k;
k = m - k;
vector<vector<int> > links(n), rlinks(n);
vector<int> degsIn(n, 0), degsOut(n, 0);
for(int i = 0; i < m; ++i)
{
int src, dest;
cin >> src >> dest;
--src, --dest;
links[src].push_back(dest);
rlinks[dest].push_back(src);
degsIn[dest]++;
degsOut[src]++;
}
for(int i = 0; i < k; ++i)
{
int max_d = Max_diff(degsIn, degsOut);
if(degsOut[max_d] >= degsIn[max_d])
{
//out_degree > in_degree
//In max_d's adj_vex, find a maximum (in_degree - out_degree)
int sec_d = Sec_diff(links[max_d], degsIn, degsOut, 0);
Del_nodes(links[max_d], sec_d);
Del_nodes(rlinks[sec_d], max_d);
degsOut[max_d]--;
degsIn[sec_d]--;
}
else
{
//in_degree > out_degree
int sec_d = Sec_diff(rlinks[max_d], degsIn, degsOut, 1);
Del_nodes(rlinks[max_d], sec_d);
Del_nodes(links[sec_d], max_d);
degsIn[max_d]--;
degsOut[sec_d]--;
}
}
int max_d = Max_diff(degsIn, degsOut);
cout << "Case " << iCase << ": " << (int)abs((double)degsIn[max_d] - (double)degsOut[max_d]) << endl;
}
return 0;
}
#include <vector>
#include <utility>
#include <cmath>
using namespace std;
int Max_diff(vector<int>& degsIn, vector<int>& degsOut)
{
int size = degsIn.size();
int max = 0, res = 0;
for(int i = 0; i < size; ++i)
{
int temp = (int)abs((double)degsIn[i] - (double)degsOut[i]);
if(max < temp)
{
max = temp;
res = i;
}
}
return res;
}
int Sec_diff(vector<int>& nodes, vector<int>& degsIn, vector<int>& degsOut, int flag)
{
int max = -1000024, pos ;
for(int i = 0; i < nodes.size(); ++i)
{
if(nodes[i] < 0)
continue;
int temp = degsIn[nodes[i]] - degsOut[nodes[i]];
if( flag )
{
temp = -temp;
}
if( max < temp)
{
max = temp;
pos = i;
}
}
return nodes[pos];
}
void Del_nodes(vector<int>& nodes, int v)
{
for(int i = 0; i < nodes.size(); ++i)
if(nodes[i] == v)
{
nodes[i] = -1;
return ;
}
}
int main()
{
int T;
cin >> T;
for(int iCase = 1; iCase <= T; ++iCase)
{
int n, m, k;
cin >> n >> m >> k;
k = m - k;
vector<vector<int> > links(n), rlinks(n);
vector<int> degsIn(n, 0), degsOut(n, 0);
for(int i = 0; i < m; ++i)
{
int src, dest;
cin >> src >> dest;
--src, --dest;
links[src].push_back(dest);
rlinks[dest].push_back(src);
degsIn[dest]++;
degsOut[src]++;
}
for(int i = 0; i < k; ++i)
{
int max_d = Max_diff(degsIn, degsOut);
if(degsOut[max_d] >= degsIn[max_d])
{
//out_degree > in_degree
//In max_d's adj_vex, find a maximum (in_degree - out_degree)
int sec_d = Sec_diff(links[max_d], degsIn, degsOut, 0);
Del_nodes(links[max_d], sec_d);
Del_nodes(rlinks[sec_d], max_d);
degsOut[max_d]--;
degsIn[sec_d]--;
}
else
{
//in_degree > out_degree
int sec_d = Sec_diff(rlinks[max_d], degsIn, degsOut, 1);
Del_nodes(rlinks[max_d], sec_d);
Del_nodes(links[sec_d], max_d);
degsIn[max_d]--;
degsOut[sec_d]--;
}
}
int max_d = Max_diff(degsIn, degsOut);
cout << "Case " << iCase << ": " << (int)abs((double)degsIn[max_d] - (double)degsOut[max_d]) << endl;
}
return 0;
}
在上述代碼裏面(int)abs((double)degsIn[max_d] - (double)degsOut[max_d]) 改成
abs(degsIn[max_d]-degsOut[max_d])在雲IDE裏面編譯不過,原因是重載abs(float)與abs(double)不知道調用哪個,這個問題至今還是有點困惑。。。。
求高手指點。。。。。。。。