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)不知道调用哪个,这个问题至今还是有点困惑。。。。
求高手指点。。。。。。。。