codeforce 605B. Lazy Student

题意: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 }
View Code
原文地址:https://www.cnblogs.com/ITUPC/p/5040992.html