#include <bits/stdc++.h>
using namespace std;
typedef long long int lli;
const int MAXN = 210;
const int INF = 1000;
struct edge
{
int U, V;
lli t, c;
lli val;
edge(int U, int V, lli t, lli c) : U(U), V(V), t(t), c(c) {}
bool operator < (edge a) { return val < a.val; }
};
class UnionFind
{
public:
int find(int cur)
{
if( pai[cur] == cur ) return cur;
return pai[cur] = find( pai[cur] );
}
bool same(int U, int V) { return find( U ) == find( V ); }
void join(int i, int j)
{
i = find( i ); j = find( j );
if( i == j ) return;
if( peso[i] < peso[j] ) swap( i , j );
pai[j] = i;
if( peso[i] == peso[j] ) peso[i]++;
}
void init(int n)
{
for(int i = 1 ; i <= n ; i++)
{
pai[i] = i;
peso[i] = 0;
}
}
private:
int pai[MAXN];
int peso[MAXN];
};
int n, m;
lli optX;
lli optY;
lli optVal;
vector< edge > ans;
vector< edge > sweep;
UnionFind DSU;
void updateAnswer(lli val, lli X, lli Y)
{
if( val >= optVal ) return;
optX = X;
optY = Y;
optVal = val;
}
void buildMST(lli X, lli Y, lli& sT, lli& sC, bool answer = false)
{
sT = sC = 0;
DSU.init( n );
for(int i = 0 ; i < m ; i++)
{
lli T = sweep[i].t;
lli C = sweep[i].c;
sweep[i].val = X*T + Y*C;
}
sort( sweep.begin() , sweep.end() );
for(int i = 0 ; i < m ; i++)
{
int U = sweep[i].U;
int V = sweep[i].V;
if( !DSU.same( U , V ) )
{
DSU.join( U , V );
sT += sweep[i].t;
sC += sweep[i].c;
if( answer ) ans.push_back( sweep[i] );
}
}
}
void lowerHull(lli x1, lli y1, lli x2, lli y2)
{
lli dX = abs( x1 - x2 );
lli dY = abs( y1 - y2 );
lli newX, newY;
buildMST( dY , dX , newX , newY );
if( (y2 - y1)*(newX - x1) == (newY - y1)*(x2 - x1) ) return;
updateAnswer( newX*newY , dY , dX );
lowerHull( x1 , y1 , newX , newY );
lowerHull( newX , newY , x2 , y2 );
}
int main()
{
scanf("%d %d",&n,&m);
optVal = 1000000000000000000LL;
for(int i = 1 ; i <= m ; i++)
{
int U, V;
lli t, c;
scanf("%d %d %lld %lld",&U,&V,&t,&c);
U++; V++;
sweep.push_back( edge( U , V , t , c ) );
}
lli x1, y1;
buildMST( INF , 1 , x1 , y1 );
lli x2, y2;
buildMST( 1 , INF , x2 , y2 );
updateAnswer( x1*y1 , INF , 1 );
updateAnswer( x2*y2 , 1 , INF );
lowerHull( x1 , y1 , x2 , y2 );
lli sT, sC;
buildMST( optX , optY , sT , sC , true );
printf("%lld %lld\n",sT,sC);
for(int i = 0 ; i < n - 1 ; i++)
printf("%d %d\n",ans[i].U - 1,ans[i].V - 1);
}
Compilation message
timeismoney.cpp: In function 'int main()':
timeismoney.cpp:130:7: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
scanf("%d %d",&n,&m);
~~~~~^~~~~~~~~~~~~~~
timeismoney.cpp:138:8: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
scanf("%d %d %lld %lld",&U,&V,&t,&c);
~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
5 ms |
376 KB |
Output is correct |
2 |
Correct |
5 ms |
256 KB |
Output is correct |
3 |
Correct |
5 ms |
256 KB |
Output is correct |
4 |
Correct |
5 ms |
376 KB |
Output is correct |
5 |
Correct |
5 ms |
376 KB |
Output is correct |
6 |
Correct |
5 ms |
376 KB |
Output is correct |
7 |
Correct |
6 ms |
504 KB |
Output is correct |
8 |
Correct |
12 ms |
1140 KB |
Output is correct |
9 |
Correct |
5 ms |
256 KB |
Output is correct |
10 |
Correct |
5 ms |
256 KB |
Output is correct |
11 |
Correct |
5 ms |
256 KB |
Output is correct |
12 |
Correct |
5 ms |
256 KB |
Output is correct |
13 |
Correct |
5 ms |
376 KB |
Output is correct |
14 |
Correct |
8 ms |
376 KB |
Output is correct |
15 |
Correct |
7 ms |
376 KB |
Output is correct |
16 |
Correct |
51 ms |
632 KB |
Output is correct |
17 |
Correct |
53 ms |
504 KB |
Output is correct |
18 |
Correct |
51 ms |
504 KB |
Output is correct |
19 |
Correct |
394 ms |
1140 KB |
Output is correct |
20 |
Correct |
405 ms |
1144 KB |
Output is correct |