Pagini recente » Cod sursa (job #3172267) | Cod sursa (job #1430328) | Cod sursa (job #3236802) | Cod sursa (job #698121) | Cod sursa (job #3226846)
#include <iostream>
#include <queue>
#include <vector>
#include <stack>
#include <fstream>
#define MAXN 200000
#define DEBUG 0
using namespace std;
struct Edge{
int b, cost;
};
struct EdgeFull{
int parent, id, cost;
};
vector<vector<Edge>> v;
int r[MAXN];
vector<int> nodeComponents[MAXN];
vector<vector<int>> components;
stack<EdgeFull> edges;
int punte[MAXN];
void popComponent(int id, int parent){
EdgeFull lastEdge;
components.push_back({});
int compid = components.size() - 1;
while(!edges.empty() && !(edges.top().parent == parent && edges.top().id == id)){
nodeComponents[edges.top().id].push_back(compid);
components[compid].push_back(edges.top().id);
lastEdge = edges.top();
edges.pop();
}
nodeComponents[edges.top().id].push_back(compid);
components[compid].push_back(edges.top().id);
if(components[compid].size() == 2)
punte[compid] = lastEdge.cost;
}
int first[MAXN], x = 1, les[MAXN];
void getComponents(int id, int parent, int cost){
edges.push({parent, id, cost});
first[id] = x;
x ++;
les[id] = first[id];
int nrc = 0;
for(int i = 0; i < v[id].size(); i ++){
int other = v[id][i].b;
if(other != parent){
if(first[other] == 0){ // Front Edge
getComponents(other, id, v[id][i].cost);
nrc ++;
if(les[other] >= first[id]){ // Daca copilul asta nu poate ajunge mai sus
// articulation[id] = true;
popComponent(id, parent);
}
}
if(les[other] < les[id])
les[id] = les[other];
}
}
// if(first[id] == 1 && nrc > 1){ // Primul vizitat trebuie sa aiba minim 2 copii
// articulation[id] = 1;
// } else if(first[id] == 1)
// articulation[id] = 0;
}
struct Frame{
int id, minv;
};
queue<Frame> cd; // Nodurile in care am ajuns
bool visitedComponent[MAXN], visitedNode[MAXN];
int minRoad[MAXN]; // minRoad[i] = Puntea minima dintre nodul id si nodul i
int n;
long long componentDfs(int start){
cd.push({start, -1});
for(int i = 0; i < components.size(); i ++)
visitedComponent[i] = false;
for(int i = 0; i < n; i ++)
visitedNode[i] = false;
while(!cd.empty()){
int id = cd.front().id, minv = cd.front().minv;
cd.pop();
for(int i = 0; i < nodeComponents[id].size(); i ++){
int comp = nodeComponents[id][i];
int nminv = minv;
if(!visitedComponent[comp]){ // Adaugam elementele din componenta curenta
visitedComponent[comp] = true;
if(components[comp].size() == 2){ // Este o punte
if(nminv == -1 || nminv > punte[comp])
nminv = punte[comp];
}
for(int j = 0; j < components[comp].size(); j ++){
if(!visitedNode[components[comp][j]]){
visitedNode[components[comp][j]] = true;
cd.push({components[comp][j], nminv});
minRoad[components[comp][j]] = nminv;
}
}
}
}
}
if(DEBUG)
printf("%d:\n", start + 1);
long long sum = 0;
for(int i = 0; i < n; i ++){
if(i != start){
int val;
if(minRoad[i] == -1)
val = r[start];
else
val = min(r[start], minRoad[i]);
sum += val;
if(DEBUG)
printf("%d ", val);
} else if(DEBUG)
printf("X ");
}
if(DEBUG)
printf("\n");
return sum;
}
int main(){
int m;
ifstream fin ("biconex.in");
fin >> n >> m;
// for(int i = 0; i < n; i ++)
// fin >> r[i];
v.resize(n);
for(int i = 0; i < m; i++){
int a, b, c;
fin >> a >> b;
// fin >> c;
a --;
b --;
v[a].push_back({b, c});
v[b].push_back({a, c});
}
fin.close();
getComponents(0, -1, 0);
if(DEBUG){
for(int i = 0; i < n; i ++)
printf("%d ", first[i]);
printf("\n");
for(int i = 0; i < n; i ++)
printf("%d ", les[i]);
printf("\n");
// for(int i = 0; i < n; i ++)
// printf("%d ", articulation[i]);
// printf("\n\n");
printf("Components by nodes\n");
for(int i = 0; i < n; i ++){
printf("%d: ", i + 1);
for(int j = 0; j < nodeComponents[i].size(); j ++){
printf("%d ", nodeComponents[i][j]);
}
printf("\n");
}
printf("\nNodes by components\n");
for(int i = 0; i < components.size(); i ++){
printf("%d: ", i);
for(int j = 0; j < components[i].size(); j ++){
printf("%d ", components[i][j] + 1);
}
printf("\n");
}
printf("\n");
}
ofstream fout ("biconex.out");
// for(int i = 0; i < n; i ++){
// fout << componentDfs(i) << endl;
// }
fout << components.size() << "\n";
for(int i = 0; i < components.size(); i ++){
for(int j = 0; j < components[i].size(); j ++)
fout << components[i][j] + 1 << " ";
fout << "\n";
}
fout.close();
return 0;
}