思路:有两种没有边权但是有染色的边,现在问时候能够形成确切的含有K条Blue边的生成树。直接找是不现实的,但是我们可以看至少和之多需要多少条就行了,只要K在这两个值之间就行了。因为从最少的Blue边开始,用blue边替换RED边,这样是可以形成环的,所以替换是可行的,这样就可以一步一步替换成含有k条blue边的生成树。
// #pragma comment(linker, "/STACK:1024000000,1024000000") #include <iostream> #include <algorithm> #include <iomanip> #include <sstream> #include <string> #include <stack> #include <queue> #include <deque> #include <vector> #include <map> #include <set> #include <cstdio> #include <cstring> #include <cmath> #include <cstdlib> #include <climits> using namespace std; // #define DEBUG #ifdef DEBUG #define debug(...) printf( __VA_ARGS__ ) #else #define debug(...) #endif #define CLR(x) memset(x, 0,sizeof x) #define MEM(x,y) memset(x, y,sizeof x) #define pk push_back template<class T> inline T Get_Max(const T&a,const T&b){return a < b?b:a;} template<class T> inline T Get_Min(const T&a,const T&b){return a < b?a:b;} typedef long long LL; typedef unsigned long long ULL; typedef pair<int,int> ii; const double eps = 1e-10; const int inf = 1 << 30; const int INF = 0x3f3f3f3f; const int MOD = 1e9 + 7; const int maxn = 1010; int n,m,k; struct Edge{ int u, v, w; Edge(){} Edge(int _u,int _v,int _w):u(_u),v(_v),w(_w){} bool operator < (const Edge& rhs)const{ return w < rhs.w; } }E[maxn*10000]; int F[maxn]; int Find(int x){ if (F[x]==-1) return x; return F[x] = Find(F[x]); } int cnt; int solve(){ memset(F, -1,sizeof F); int ans = 0; int sum = 0; sort(E,E+cnt); for (int i = 0;i < cnt;++i){ int t1 = Find(E[i].u); int t2 = Find(E[i].v); if (t1 != t2){ F[t1] = t2; sum += E[i].w; ans++; } if (ans==n-1)return sum; } if (ans==n-1) return sum; return INF; } int main() { // freopen("in.txt","r",stdin); // freopen("out.txt","w",stdout); while(scanf("%d%d%d",&n,&m,&k) != EOF){ if (n==0&&m==0&&k==0)break; cnt=0; char op[10]; int x,y; for (int i = 0;i < m;++i){ scanf("%s",op); scanf("%d%d",&x,&y); E[cnt++] = Edge(x,y,op[0]=='B'?0:1); } int ans = solve(); for (int i = 0;i < cnt;++i){ E[i].w = 1 - E[i].w; } int sum = solve(); if (ans != INF){ ans = (n-1) - ans; if (sum <= k && k <= ans){ cout << 1 << endl; continue; } } cout << 0 << endl; } return 0; }