// c++ program to find uhortest weighted
// cycle in undirected graph
#include <iostream>
#include <list>
#include <utility>
#include <vector>
#include <algorithm>
#include <set>
#include <climits>
using namespace std;
# define INF 0x3f3f3f3f
struct Edge
{
int u;
int v;
int weight;
};
// weighted undirected Graph
class Graph
{
int V;
list < pair <int, int > >* adj;
// used to store all edge information
vector < Edge > edge;
vector<int> pi;
public:
Graph(int V)
{
this->V = V;
adj = new list < pair <int, int > >[V];
pi.assign(V, INF);
}
void addEdge(int u, int v, int w);
void removeEdge(int u, int v, int w);
int ShortestPath(int u, int v);
void RemoveEdge(int u, int v);
void FindMinimumCycle();
};
//function add edge to graph
void Graph::addEdge(int u, int v, int w)
{
adj[u].push_back(make_pair(v, w));
adj[v].push_back(make_pair(u, w));
// add Edge to edge list
Edge e{ u, v, w };
edge.push_back(e);
}
// function remove edge from undirected graph
void Graph::removeEdge(int u, int v, int w)
{
adj[u].remove(make_pair(v, w));
adj[v].remove(make_pair(u, w));
}
// find shortest path from source to sink using
// Dijkstra’s shortest path algorithm [ Time complexity
// O(E logV )]
int Graph::ShortestPath(int u, int v) //uはソース、vはシンク
{
pi.assign(V, INF);
// Create a set to store vertices that are being
// prerocessed
set< pair<int, int> > setds;
// Create a vector for distances and initialize all
// distances as infinite (INF)
vector<int> dist(V, INF); //値がINFであるV個の要素からなるベクター
// Insert source itself in Set and initialize its
// distance as 0.
setds.insert(make_pair(0, u)); //ペアの最初の要素は距離、2番目の要素は点のラベル
dist[u] = 0;
/* Looping till all shortest distance are finalized
then setds will become empty */
while (!setds.empty())
{
// The first vertex in Set is the minimum distance
// vertex, extract it from set.
pair<int, int> tmp = *(setds.begin());
setds.erase(setds.begin());
// vertex label is stored in second of pair (it
// has to be done this way to keep the vertices
// sorted distance (distance must be first item
// in pair)
int u = tmp.second;
// 'i' is used to get all adjacent vertices of
// a vertex
list< pair<int, int> >::iterator i;
for (i = adj[u].begin(); i != adj[u].end(); ++i) //uに隣接するすべての点に対して
{
// Get vertex label and weight of current adjacent
// of u.
int v = (*i).first; //uに隣接する点のラベル
int weight = (*i).second; //辺(u, v)の重み
// If there is shorter path to v through u.
if (dist[v] > dist[u] + weight)
{
/* If distance of v is not INF then it must be in
our set, so removing it and inserting again
with updated less distance.
Note : We extract only those vertices from Set
for which distance is finalized. So for them,
we would never reach here. */
if (dist[v] != INF) //vの暫定的な距離が∞でないということは、既に、(dist[v], v)はsetdsに入っているので、消去する。(↓でdist[v]を更新して再度setdsに挿入している。)
setds.erase(setds.find(make_pair(dist[v], v)));
// Updating distance of v
dist[v] = dist[u] + weight;
setds.insert(make_pair(dist[v], v));
pi[v] = u;
}
}
}
// return shortest path from current source to sink
return dist[v];
}
// function return minimum weighted cycle
//int Graph::FindMinimumCycle()
void Graph::FindMinimumCycle()
{
int min_cycle = INT_MAX;
int E = edge.size();
vector<int> pi2;
int u = 0, v = 0;
for (int i = 0; i < E; i++)
{
// current Edge information
Edge e = edge[i];
// get current edge vertices which we currently
// remove from graph and then find shortest path
// between these two vertices using Dijkstra’s
// shortest path algorithm .
removeEdge(e.u, e.v, e.weight);
// minimum distance between these two vertices
int distance = ShortestPath(e.u, e.v);
// to make a cycle we have to add weight of
// currently removed edge if this is the shortest
// cycle then update min_cycle
//min_cycle = min(min_cycle, distance + e.weight);
if (distance + e.weight < min_cycle)
{
min_cycle = distance + e.weight;
pi2 = pi;
u = e.u;
v = e.v;
}
// add current edge back to the graph
addEdge(e.u, e.v, e.weight);
}
// return shortest cycle
//return min_cycle;
std::cout << "A minimum weight cycle is:" << endl;
int v1;
v1 = v;
while (pi2[v1] != INF)
{
std::cout << v1 << " -> ";
v1 = pi2[v1];
}
std::cout << u << " -> " << v << endl;
std::cout << "The weight of the cycle is " << min_cycle << endl;
}
// vriver program to test above function
int main()
{
int V = 9;
Graph g(V);
// making above shown graph
g.addEdge(0, 1, 4);
g.addEdge(0, 7, 8);
g.addEdge(1, 2, 8);
g.addEdge(1, 7, 11);
g.addEdge(2, 3, 7);
g.addEdge(2, 8, 2);
g.addEdge(2, 5, 4);
g.addEdge(3, 4, 9);
g.addEdge(3, 5, 14);
g.addEdge(4, 5, 10);
g.addEdge(5, 6, 2);
g.addEdge(6, 7, 1);
g.addEdge(6, 8, 6);
g.addEdge(7, 8, 7);
g.FindMinimumCycle();
return 0;
}
Ly8gYysrIHByb2dyYW0gdG8gZmluZCB1aG9ydGVzdCB3ZWlnaHRlZCAKLy8gY3ljbGUgaW4gdW5kaXJlY3RlZCBncmFwaCAKCiNpbmNsdWRlIDxpb3N0cmVhbT4KI2luY2x1ZGUgPGxpc3Q+CiNpbmNsdWRlIDx1dGlsaXR5PgojaW5jbHVkZSA8dmVjdG9yPgojaW5jbHVkZSA8YWxnb3JpdGhtPgojaW5jbHVkZSA8c2V0PgojaW5jbHVkZSA8Y2xpbWl0cz4KdXNpbmcgbmFtZXNwYWNlIHN0ZDsKIyBkZWZpbmUgSU5GIDB4M2YzZjNmM2YgCnN0cnVjdCBFZGdlCnsKCWludCB1OwoJaW50IHY7CglpbnQgd2VpZ2h0Owp9OwoKLy8gd2VpZ2h0ZWQgdW5kaXJlY3RlZCBHcmFwaCAKY2xhc3MgR3JhcGgKewoJaW50IFY7CglsaXN0IDwgcGFpciA8aW50LCBpbnQgPiA+KiBhZGo7CgoJLy8gdXNlZCB0byBzdG9yZSBhbGwgZWRnZSBpbmZvcm1hdGlvbiAKCXZlY3RvciA8IEVkZ2UgPiBlZGdlOwoJdmVjdG9yPGludD4gcGk7CgoKcHVibGljOgoJR3JhcGgoaW50IFYpCgl7CgkJdGhpcy0+ViA9IFY7CgkJYWRqID0gbmV3IGxpc3QgPCBwYWlyIDxpbnQsIGludCA+ID5bVl07CgkJcGkuYXNzaWduKFYsIElORik7Cgl9CgoJdm9pZCBhZGRFZGdlKGludCB1LCBpbnQgdiwgaW50IHcpOwoJdm9pZCByZW1vdmVFZGdlKGludCB1LCBpbnQgdiwgaW50IHcpOwoJaW50IFNob3J0ZXN0UGF0aChpbnQgdSwgaW50IHYpOwoJdm9pZCBSZW1vdmVFZGdlKGludCB1LCBpbnQgdik7Cgl2b2lkIEZpbmRNaW5pbXVtQ3ljbGUoKTsKCn07CgovL2Z1bmN0aW9uIGFkZCBlZGdlIHRvIGdyYXBoIAp2b2lkIEdyYXBoOjphZGRFZGdlKGludCB1LCBpbnQgdiwgaW50IHcpCnsKCWFkalt1XS5wdXNoX2JhY2sobWFrZV9wYWlyKHYsIHcpKTsKCWFkalt2XS5wdXNoX2JhY2sobWFrZV9wYWlyKHUsIHcpKTsKCgkvLyBhZGQgRWRnZSB0byBlZGdlIGxpc3QgCglFZGdlIGV7IHUsIHYsIHcgfTsKCWVkZ2UucHVzaF9iYWNrKGUpOwp9CgovLyBmdW5jdGlvbiByZW1vdmUgZWRnZSBmcm9tIHVuZGlyZWN0ZWQgZ3JhcGggCnZvaWQgR3JhcGg6OnJlbW92ZUVkZ2UoaW50IHUsIGludCB2LCBpbnQgdykKewoJYWRqW3VdLnJlbW92ZShtYWtlX3BhaXIodiwgdykpOwoJYWRqW3ZdLnJlbW92ZShtYWtlX3BhaXIodSwgdykpOwp9CgovLyBmaW5kIHNob3J0ZXN0IHBhdGggZnJvbSBzb3VyY2UgdG8gc2luayB1c2luZyAKLy8gRGlqa3N0cmHigJlzIHNob3J0ZXN0IHBhdGggYWxnb3JpdGhtIFsgVGltZSBjb21wbGV4aXR5IAovLyBPKEUgbG9nViApXSAKaW50IEdyYXBoOjpTaG9ydGVzdFBhdGgoaW50IHUsIGludCB2KSAvL3Xjga/jgr3jg7zjgrnjgIF244Gv44K344Oz44KvCnsKCXBpLmFzc2lnbihWLCBJTkYpOwoJLy8gQ3JlYXRlIGEgc2V0IHRvIHN0b3JlIHZlcnRpY2VzIHRoYXQgYXJlIGJlaW5nIAoJLy8gcHJlcm9jZXNzZWQgCglzZXQ8IHBhaXI8aW50LCBpbnQ+ID4gc2V0ZHM7CgoJLy8gQ3JlYXRlIGEgdmVjdG9yIGZvciBkaXN0YW5jZXMgYW5kIGluaXRpYWxpemUgYWxsIAoJLy8gZGlzdGFuY2VzIGFzIGluZmluaXRlIChJTkYpIAoJdmVjdG9yPGludD4gZGlzdChWLCBJTkYpOyAvL+WApOOBjElORuOBp+OBguOCi1blgIvjga7opoHntKDjgYvjgonjgarjgovjg5njgq/jgr/jg7wKCgkvLyBJbnNlcnQgc291cmNlIGl0c2VsZiBpbiBTZXQgYW5kIGluaXRpYWxpemUgaXRzIAoJLy8gZGlzdGFuY2UgYXMgMC4gCglzZXRkcy5pbnNlcnQobWFrZV9wYWlyKDAsIHUpKTsgLy/jg5rjgqLjga7mnIDliJ3jga7opoHntKDjga/ot53pm6LjgIEy55Wq55uu44Gu6KaB57Sg44Gv54K544Gu44Op44OZ44OrCglkaXN0W3VdID0gMDsKCgkvKiBMb29waW5nIHRpbGwgYWxsIHNob3J0ZXN0IGRpc3RhbmNlIGFyZSBmaW5hbGl6ZWQKCXRoZW4gc2V0ZHMgd2lsbCBiZWNvbWUgZW1wdHkgKi8KCXdoaWxlICghc2V0ZHMuZW1wdHkoKSkKCXsKCQkvLyBUaGUgZmlyc3QgdmVydGV4IGluIFNldCBpcyB0aGUgbWluaW11bSBkaXN0YW5jZSAKCQkvLyB2ZXJ0ZXgsIGV4dHJhY3QgaXQgZnJvbSBzZXQuIAoJCXBhaXI8aW50LCBpbnQ+IHRtcCA9ICooc2V0ZHMuYmVnaW4oKSk7CgkJc2V0ZHMuZXJhc2Uoc2V0ZHMuYmVnaW4oKSk7CgoJCS8vIHZlcnRleCBsYWJlbCBpcyBzdG9yZWQgaW4gc2Vjb25kIG9mIHBhaXIgKGl0IAoJCS8vIGhhcyB0byBiZSBkb25lIHRoaXMgd2F5IHRvIGtlZXAgdGhlIHZlcnRpY2VzIAoJCS8vIHNvcnRlZCBkaXN0YW5jZSAoZGlzdGFuY2UgbXVzdCBiZSBmaXJzdCBpdGVtIAoJCS8vIGluIHBhaXIpIAoJCWludCB1ID0gdG1wLnNlY29uZDsKCgkJLy8gJ2knIGlzIHVzZWQgdG8gZ2V0IGFsbCBhZGphY2VudCB2ZXJ0aWNlcyBvZiAKCQkvLyBhIHZlcnRleCAKCQlsaXN0PCBwYWlyPGludCwgaW50PiA+OjppdGVyYXRvciBpOwoJCWZvciAoaSA9IGFkalt1XS5iZWdpbigpOyBpICE9IGFkalt1XS5lbmQoKTsgKytpKSAvL3XjgavpmqPmjqXjgZnjgovjgZnjgbnjgabjga7ngrnjgavlr77jgZfjgaYKCQl7CgkJCS8vIEdldCB2ZXJ0ZXggbGFiZWwgYW5kIHdlaWdodCBvZiBjdXJyZW50IGFkamFjZW50IAoJCQkvLyBvZiB1LiAKCQkJaW50IHYgPSAoKmkpLmZpcnN0OyAvL3XjgavpmqPmjqXjgZnjgovngrnjga7jg6njg5njg6sKCQkJaW50IHdlaWdodCA9ICgqaSkuc2Vjb25kOyAvL+i+uih1LCB2KeOBrumHjeOBvwoKCQkJLy8gSWYgdGhlcmUgaXMgc2hvcnRlciBwYXRoIHRvIHYgdGhyb3VnaCB1LiAKCQkJaWYgKGRpc3Rbdl0gPiBkaXN0W3VdICsgd2VpZ2h0KQoJCQl7CgkJCQkvKiBJZiBkaXN0YW5jZSBvZiB2IGlzIG5vdCBJTkYgdGhlbiBpdCBtdXN0IGJlIGluCgkJCQkJb3VyIHNldCwgc28gcmVtb3ZpbmcgaXQgYW5kIGluc2VydGluZyBhZ2FpbgoJCQkJCXdpdGggdXBkYXRlZCBsZXNzIGRpc3RhbmNlLgoJCQkJCU5vdGUgOiBXZSBleHRyYWN0IG9ubHkgdGhvc2UgdmVydGljZXMgZnJvbSBTZXQKCQkJCQlmb3Igd2hpY2ggZGlzdGFuY2UgaXMgZmluYWxpemVkLiBTbyBmb3IgdGhlbSwKCQkJCQl3ZSB3b3VsZCBuZXZlciByZWFjaCBoZXJlLiAqLwoJCQkJaWYgKGRpc3Rbdl0gIT0gSU5GKSAvL3bjga7mmqvlrprnmoTjgarot53pm6LjgYziiJ7jgafjgarjgYTjgajjgYTjgYbjgZPjgajjga/jgIHml6LjgavjgIEoZGlzdFt2XSwgdinjga9zZXRkc+OBq+WFpeOBo+OBpuOBhOOCi+OBruOBp+OAgea2iOWOu+OBmeOCi+OAgu+8iOKGk+OBp2Rpc3Rbdl3jgpLmm7TmlrDjgZfjgablho3luqZzZXRkc+OBq+aMv+WFpeOBl+OBpuOBhOOCi+OAgu+8iQoJCQkJCXNldGRzLmVyYXNlKHNldGRzLmZpbmQobWFrZV9wYWlyKGRpc3Rbdl0sIHYpKSk7CgoJCQkJLy8gVXBkYXRpbmcgZGlzdGFuY2Ugb2YgdiAKCQkJCWRpc3Rbdl0gPSBkaXN0W3VdICsgd2VpZ2h0OwoJCQkJc2V0ZHMuaW5zZXJ0KG1ha2VfcGFpcihkaXN0W3ZdLCB2KSk7CgkJCQlwaVt2XSA9IHU7CgkJCX0KCQl9Cgl9CgoJLy8gcmV0dXJuIHNob3J0ZXN0IHBhdGggZnJvbSBjdXJyZW50IHNvdXJjZSB0byBzaW5rIAoJcmV0dXJuIGRpc3Rbdl07Cn0KCi8vIGZ1bmN0aW9uIHJldHVybiBtaW5pbXVtIHdlaWdodGVkIGN5Y2xlIAovL2ludCBHcmFwaDo6RmluZE1pbmltdW1DeWNsZSgpCnZvaWQgR3JhcGg6OkZpbmRNaW5pbXVtQ3ljbGUoKQp7CglpbnQgbWluX2N5Y2xlID0gSU5UX01BWDsKCWludCBFID0gZWRnZS5zaXplKCk7Cgl2ZWN0b3I8aW50PiBwaTI7CglpbnQgdSA9IDAsIHYgPSAwOwoJZm9yIChpbnQgaSA9IDA7IGkgPCBFOyBpKyspCgl7CgkJLy8gY3VycmVudCBFZGdlIGluZm9ybWF0aW9uIAoJCUVkZ2UgZSA9IGVkZ2VbaV07CgoJCS8vIGdldCBjdXJyZW50IGVkZ2UgdmVydGljZXMgd2hpY2ggd2UgY3VycmVudGx5IAoJCS8vIHJlbW92ZSBmcm9tIGdyYXBoIGFuZCB0aGVuIGZpbmQgc2hvcnRlc3QgcGF0aCAKCQkvLyBiZXR3ZWVuIHRoZXNlIHR3byB2ZXJ0aWNlcyB1c2luZyBEaWprc3RyYeKAmXMgCgkJLy8gc2hvcnRlc3QgcGF0aCBhbGdvcml0aG0gLiAKCQlyZW1vdmVFZGdlKGUudSwgZS52LCBlLndlaWdodCk7CgoJCS8vIG1pbmltdW0gZGlzdGFuY2UgYmV0d2VlbiB0aGVzZSB0d28gdmVydGljZXMgCgkJaW50IGRpc3RhbmNlID0gU2hvcnRlc3RQYXRoKGUudSwgZS52KTsKCgkJLy8gdG8gbWFrZSBhIGN5Y2xlIHdlIGhhdmUgdG8gYWRkIHdlaWdodCBvZiAKCQkvLyBjdXJyZW50bHkgcmVtb3ZlZCBlZGdlIGlmIHRoaXMgaXMgdGhlIHNob3J0ZXN0IAoJCS8vIGN5Y2xlIHRoZW4gdXBkYXRlIG1pbl9jeWNsZSAKCQkvL21pbl9jeWNsZSA9IG1pbihtaW5fY3ljbGUsIGRpc3RhbmNlICsgZS53ZWlnaHQpOwoJCWlmIChkaXN0YW5jZSArIGUud2VpZ2h0IDwgbWluX2N5Y2xlKQoJCXsKCQkJbWluX2N5Y2xlID0gZGlzdGFuY2UgKyBlLndlaWdodDsKCQkJcGkyID0gcGk7CgkJCXUgPSBlLnU7CgkJCXYgPSBlLnY7CgkJfQoKCQkvLyBhZGQgY3VycmVudCBlZGdlIGJhY2sgdG8gdGhlIGdyYXBoIAoJCWFkZEVkZ2UoZS51LCBlLnYsIGUud2VpZ2h0KTsKCX0KCgoJLy8gcmV0dXJuIHNob3J0ZXN0IGN5Y2xlIAoJLy9yZXR1cm4gbWluX2N5Y2xlOwoKCXN0ZDo6Y291dCA8PCAiQSBtaW5pbXVtIHdlaWdodCBjeWNsZSBpczoiIDw8IGVuZGw7CgoJaW50IHYxOwoJdjEgPSB2OwoJd2hpbGUgKHBpMlt2MV0gIT0gSU5GKQoJewoJCXN0ZDo6Y291dCA8PCB2MSA8PCAiIC0+ICI7CgkJdjEgPSBwaTJbdjFdOwoJfQoJc3RkOjpjb3V0IDw8IHUgPDwgIiAtPiAiIDw8IHYgPDwgZW5kbDsKCglzdGQ6OmNvdXQgPDwgIlRoZSB3ZWlnaHQgb2YgdGhlIGN5Y2xlIGlzICIgPDwgbWluX2N5Y2xlIDw8IGVuZGw7Cn0KCi8vIHZyaXZlciBwcm9ncmFtIHRvIHRlc3QgYWJvdmUgZnVuY3Rpb24gCmludCBtYWluKCkKewoJaW50IFYgPSA5OwoJR3JhcGggZyhWKTsKCgkvLyBtYWtpbmcgYWJvdmUgc2hvd24gZ3JhcGggCglnLmFkZEVkZ2UoMCwgMSwgNCk7CglnLmFkZEVkZ2UoMCwgNywgOCk7CglnLmFkZEVkZ2UoMSwgMiwgOCk7CglnLmFkZEVkZ2UoMSwgNywgMTEpOwoJZy5hZGRFZGdlKDIsIDMsIDcpOwoJZy5hZGRFZGdlKDIsIDgsIDIpOwoJZy5hZGRFZGdlKDIsIDUsIDQpOwoJZy5hZGRFZGdlKDMsIDQsIDkpOwoJZy5hZGRFZGdlKDMsIDUsIDE0KTsKCWcuYWRkRWRnZSg0LCA1LCAxMCk7CglnLmFkZEVkZ2UoNSwgNiwgMik7CglnLmFkZEVkZ2UoNiwgNywgMSk7CglnLmFkZEVkZ2UoNiwgOCwgNik7CglnLmFkZEVkZ2UoNywgOCwgNyk7CgoJZy5GaW5kTWluaW11bUN5Y2xlKCk7CglyZXR1cm4gMDsKfQo=