codeforces 700C

来源:互联网 发布:红米清空数据失败 编辑:程序博客网 时间:2024/06/10 19:09
题目:图上删除最多两条边使得两个点不连通,要求删除的边权和最小。解法:枚举一条可达路径上的边,tarjan找割边。复杂度O(n*m)

#include<bits/stdc++.h>
using namespace std;typedef long long LL;struct Edge{int st,ed,id,w,next;bool edge_cut,deleted;Edge(){}Edge(int st,int ed,int id,int w):st(st),ed(ed),id(id),w(w){edge_cut = deleted = false;}};class Solution{vector<Edge> _edge;vector<int> head;vector<bool> vi;int idx,n;public:void init(int n,int m){this->n = n;_edge = vector<Edge>(m);head = vector<int>(n+1,-1);idx = 0;}void add_edge(int x,int y,int id,int w){_edge[idx] = Edge(x,y,id,w);_edge[idx].next = head[x];head[x] = idx++;}bool get_path(int st,int ed,vector<int> &path){path.clear();vi = vector<bool>(n+1,0);return dfs_path(st,ed,path);}//path ----- reverse pathbool dfs_path(int st,int ed,vector<int> &path){if(st == ed) return true;vi[st] = true;for(int it = head[st];it!=-1;it=_edge[it].next){Edge edge = _edge[it];if(edge.deleted) continue;if(vi[edge.ed]) continue;if(dfs_path(edge.ed,ed,path)){path.push_back(it);return true;}}return false;}vector<int> dfn,low;int tdx;void tarjan(int st){dfn = low = vector<int>(n+1,0);tdx = 1;dfs_tarjan(st,-1);}void dfs_tarjan(int st,int e){dfn[st]=low[st]=tdx++;for(int it = head[st];it!=-1;it=_edge[it].next){Edge edge = _edge[it];if(e!=-1&&it==(e^1)){//反向边不走continue;}if(edge.deleted) continue;//删除的边不走int to = edge.ed;if(dfn[to]==0){dfs_tarjan(to,it);low[st] = min(low[to],low[st]);if(low[to]>dfn[st]){_edge[it].edge_cut = _edge[it^1].edge_cut = true;}}else{low[st] = min(low[st],dfn[to]);}}}const static LL INF = 1234567891234567ll;void solve(){int n,m,st,ed;cin>>n>>m;init(n,m*2);cin>>st>>ed;for(int i=1;i<=m;i++){int x,y,w;cin>>x>>y>>w;if(x==y) continue;add_edge(x,y,i,w);add_edge(y,x,i,w);}//cout<<"Input finished!"<<endl;vector<int> path;if(!get_path(st,ed,path)){cout<<"0"<<endl<<"0"<<endl;return;}//reverse(path.begin(),path.end());//for(int i=0;i<(int)path.size();i++){//cout<<_edge[path[i]].id<<" ";//}//cout<<endl;LL retLen = INF;vector<int> retSet;for(int i=0;i<(int)path.size();i++){int eit = path[i];_edge[eit].deleted = _edge[eit^1].deleted = true;vector<int> path2;if(!get_path(st,ed,path2)){if(_edge[eit].w<retLen){retLen = _edge[eit].w;retSet.clear();retSet.push_back(_edge[eit].id);}}else{//cout<<"tarjan begin!"<<endl;tarjan(st);//cout<<"tarjan end!"<<endl;for(int j=0;j<(int)path2.size();j++){int eit2 = path2[j];if(_edge[eit2].edge_cut){if(_edge[eit].w+_edge[eit2].w<retLen){retLen = _edge[eit].w+_edge[eit2].w;retSet.clear();retSet.push_back(_edge[eit].id);retSet.push_back(_edge[eit2].id);}}}for(int j=0;j<idx;j++){_edge[j].edge_cut=false;}}_edge[eit].deleted = _edge[eit^1].deleted = false;}if(retLen<INF){cout<<retLen<<endl;cout<<retSet.size()<<endl;for(int i=0;i<(int)retSet.size();i++){cout<<retSet[i]<<" ";}cout<<endl;}else{cout<<"-1"<<endl;}}};int main(){//cout<<0x3f3f3f3f<<endl;ios_base::sync_with_stdio(0);Solution * sol = new Solution();sol->solve();return 0;}/* 6 71 62 1 62 3 53 4 94 6 44 6 54 5 13 1 3 */


0 0
原创粉丝点击