加入一个虚点 往每条边放入INF 这样的话 最多只有一条边会与他 相连
只需要记录一下第几个点是和虚点相连即可
注意!不查重比较简便!
#include<iostream>
#include<cstring>
#define INF 0x3f3f3f3f
using namespace std;
const int N = 1100,M = 11000 + N;
struct node{
int x,y,w;
}a[M];
int dis[N][N];
int n,m,idx;
int pre[N],id[N],w[N],vis[N];
int jilu;
int zhuliu(int root){
int sum = 0;
while(1){
for(int i = 0; i < n; i++){
w[i] = INF;
}
int cnt = 0;
for(int i = 0; i < idx; i++){
if(a[i].y == root) continue;
if(w[a[i].y] > a[i].w && a[i].x != a[i].y){
w[a[i].y] = a[i].w;
pre[a[i].y] = a[i].x;
if(a[i].x == root) jilu = i;
}
}
memset(id,-1,sizeof id);
memset(vis,-1,sizeof vis);
w[root] = 0;
for(int i = 0; i < n; i++) if(i != root && w[i] == INF) return -1;
for(int i = 0; i < n; i++){
sum += w[i];
int v = i;
while(v != root && vis[v] != i && id[v] == -1){
vis[v] = i;
v = pre[v];
}
if(v != root && id[v] == -1){
for(int j = pre[v]; j != v; j = pre[j]){
id[j] = cnt;
}
id[v] = cnt++;
}
}
if(!cnt) break;
for(int i = 0; i < n; i++){
if(id[i] == -1) id[i] = cnt++;
}
for(int i = 0; i < idx; i++){
int x = a[i].x,y = a[i].y;
a[i].x = id[x],a[i].y = id[y];
if(id[x] != id[y]){
a[i].w -= w[y];
}
}
n = cnt;
root = id[root];
}
return sum;
}
int main(){
while(scanf(" %d %d",&n,&m)==2){
idx = 0;
int ans = 1;
for(int i = 0; i < m; i++){
int x,y,w;
scanf("%d%d%d",&x,&y,&w);
ans += w;
a[idx++] = {
x,y,w};
}
for(int i = 0; i < n; i++){
a[idx++] = {
n,i,ans};
}
++n;
int s = zhuliu(n - 1);
if(s == -1 || s - ans >= ans) {
printf("impossible\n\n");
}else{
printf("%d %d\n\n",s - ans,jilu - m);
}
}
return 0;
}