题意:n点,m条边。m条边里面标记为1的最小生成树的边,0为非最小生成树的边。给了每条边的权,如果能构成一个最小生成树则输出图,否则-1。
思路:先按权值小,为生成数边的顺序排序。(根据kruskal)再添加每条0边。这里假定(1,3),(2,4)构成环。
1 #include<iostream> 2 #include<string> 3 #include<algorithm> 4 #include<cstdlib> 5 #include<cstdio> 6 #include<set> 7 #include<map> 8 #include<vector> 9 #include<cstring> 10 #include<stack> 11 #include<cmath> 12 #include<queue> 13 using namespace std; 14 #define CL(x,v); memset(x,v,sizeof(x)); 15 #define INF 0x3f3f3f3f 16 #define LL long long 17 const int SIGMA_SIZE = 26; 18 const int MAXNODE = 111000; 19 const int MAXS = 150 + 10; 20 21 int n,m; 22 struct node 23 { 24 int u,v,o; 25 bool operator <(const node &b)const 26 { 27 if(u==b.u) 28 return v>b.v; 29 return u<b.u; 30 } 31 } a[100010]; 32 33 int b[100010]; 34 int c[100010]; 35 int fun() 36 { 37 int e=1,x=1,y=3; 38 for(int i=1;i<=m;i++) 39 { 40 if(a[i].v) 41 { 42 b[a[i].o]=e; 43 c[a[i].o]=++e; 44 } 45 else 46 { 47 if(y>e) 48 return 0; 49 b[a[i].o]=x; 50 c[a[i].o]=y; 51 if(--x==0) 52 { 53 y+=1; 54 x=y-2; 55 } 56 } 57 } 58 return 1; 59 } 60 int main() 61 { 62 scanf("%d%d",&n,&m); 63 for(int i=1; i<=m; i++) 64 { 65 scanf("%d%d",&a[i].u,&a[i].v); 66 a[i].o=i; 67 } 68 sort(a+1,a+1+m); 69 if(fun()) 70 { 71 for(int i=1; i<=m; i++) 72 { 73 cout<<b[i]<<" "<<c[i]<<endl; 74 } 75 } 76 else 77 { 78 cout<<"-1"<<endl; 79 } 80 return 0; 81 }
时间: 2024-10-10 02:46:56