#include <tuple>
#include <vector>
#include <cstring>
#include <iostream>
using namespace std;
const int MAXN = 1005;
const int MAXLog = 20;
const long long inf = 1e15 + 5;
struct Path
{
int cost;
vector <int> part[2];
Path(){}
Path(int cost)
{
this->cost = cost;
}
};
int n, m;
vector <int> graph[MAXN];
vector <Path> node2Paths[MAXN];
int parentInd[MAXN];
int sparse[25][MAXN];
int parent[MAXN], depth[MAXN];
void DFSInit(int x, int last, int level)
{
depth[x] = level;
parent[x] = last;
for(int i = 0;i<graph[x].size();i++)
{
if(graph[x][i]==last)
{
graph[x].erase(graph[x].begin()+i);
break;
}
}
for(int i = 0;i<graph[x].size();i++)
{
parentInd[ graph[x][i] ] = i;
}
for(int y: graph[x])
{
DFSInit(y, x, level+1);
}
}
int findLCA(int u, int v)
{
if(depth[u]>depth[v]) swap(u, v);
for(int i = MAXLog;i>=0;i--)
{
if(sparse[i][v]!=-1 && depth[ sparse[i][v] ]>=depth[u])
{
v = sparse[i][v];
}
}
if(u==v) return u;
for(int i = MAXLog;i>=0;i--)
{
if(sparse[i][u]!=sparse[i][v])
{
u = sparse[i][u];
v = sparse[i][v];
}
}
return parent[u];
}
int getDist(int u, int v)
{
return depth[u] + depth[v] - 2*depth[findLCA(u, v)];
}
void init(vector <tuple <int, int, int>> &rawPaths)
{
DFSInit(1, -1, 1);
for(int x = 1;x<=n;x++) sparse[0][x] = parent[x];
for(int i = 1;i<=MAXLog;i++)
{
for(int x = 1;x<=n;x++)
{
if(sparse[i-1][x]==-1) sparse[i][x] = -1;
else sparse[i][x] = sparse[i-1][ sparse[i-1][x] ];
}
}
for(tuple <int, int, int> t: rawPaths)
{
int u = get<0>(t);
int v = get<1>(t);
int c = get<2>(t);
if(getDist(u, v)%2==1) continue;
//cout << u << " " << v << " -> lca:-" << findLCA(u, v) << '\n';
Path p(c);
int lca = findLCA(u, v);
int x = u;
while(x!=lca) p.part[0].push_back(x), x = parent[x];
x = v;
while(x!=lca) p.part[1].push_back(x), x = parent[x];
node2Paths[lca].push_back(p);
}
}
bool isCompatable(int x, int mask, Path &p)
{
bool fail = false;
for(int ind = 0;ind<2;ind++)
{
if(p.part[ind].size()>0 && ((mask>>parentInd[ p.part[ind].back() ])&1)==1) fail = true;
}
if(fail==false) return true;
return false;
}
bool checkCycle(int x, int mask)
{
for(Path p: node2Paths[x])
{
if(isCompatable(x, mask, p)==true) return true;
}
return false;
}
int updateMask(int mask, Path &p)
{
for(int ind = 0;ind<2;ind++)
{
if(p.part[ind].size()==0) continue;
mask |= (1<<parentInd[ p.part[ind].back() ]);
}
return mask;
}
long long rec(int x, int mask)
{
if(graph[x].size()==0) return 0;
long long answer = 0;
for(Path p: node2Paths[x])
{
if(isCompatable(x, mask, p)==false) continue;
int newMask = updateMask(mask, p);
long long curr = p.cost + rec(x, newMask);
for(int ind = 0;ind<2;ind++)
{
int last = -1;
for(int x: p.part[ind])
{
curr += rec(x, ((last==-1)?0:(1<<parentInd[last])));
last = x;
}
}
answer = max(answer, curr);
}
long long curr = 0;
for(int i = 0;i<graph[x].size();i++)
{
if(((mask>>i)&1)==1) continue;
curr += rec(graph[x][i], 0);
}
answer = max(answer, curr);
//cout << x << " " << mask << " -> " << answer << '\n';
return answer;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(NULL);
cin >> n >> m;
long long sumAllEdges = 0;
vector <tuple <int, int, int>> rawPaths;
for(int i = 0;i<m;i++)
{
int x, y, c;
cin >> x >> y >> c;
if(c==0)
{
graph[x].push_back(y);
graph[y].push_back(x);
}
else
{
sumAllEdges += c;
rawPaths.push_back(make_tuple(x, y, c));
}
}
init(rawPaths);
cout << sumAllEdges - rec(1, 0) << '\n';
}
Compilation message
training.cpp: In function 'void DFSInit(int, int, int)':
training.cpp:37:20: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
37 | for(int i = 0;i<graph[x].size();i++)
| ~^~~~~~~~~~~~~~~~
training.cpp:46:20: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
46 | for(int i = 0;i<graph[x].size();i++)
| ~^~~~~~~~~~~~~~~~
training.cpp: In function 'long long int rec(int, int)':
training.cpp:180:20: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
180 | for(int i = 0;i<graph[x].size();i++)
| ~^~~~~~~~~~~~~~~~
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
1 ms |
512 KB |
Output is correct |
2 |
Correct |
1 ms |
512 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Execution timed out |
1085 ms |
632 KB |
Time limit exceeded |
2 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Execution timed out |
1078 ms |
2024 KB |
Time limit exceeded |
2 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
1 ms |
512 KB |
Output is correct |
2 |
Correct |
1 ms |
512 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Correct |
1 ms |
512 KB |
Output is correct |
2 |
Correct |
1 ms |
512 KB |
Output is correct |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Execution timed out |
626 ms |
544 KB |
Time limit exceeded |
2 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Execution timed out |
1095 ms |
512 KB |
Time limit exceeded |
2 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Execution timed out |
1095 ms |
768 KB |
Time limit exceeded |
2 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Execution timed out |
1091 ms |
1152 KB |
Time limit exceeded |
2 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Execution timed out |
1038 ms |
768 KB |
Time limit exceeded |
2 |
Halted |
0 ms |
0 KB |
- |
# |
결과 |
실행 시간 |
메모리 |
Grader output |
1 |
Execution timed out |
1086 ms |
2560 KB |
Time limit exceeded |
2 |
Halted |
0 ms |
0 KB |
- |