True Liars POJ - 1417
11764 단어 함께 조사하여 모으다dp
먼저 하나의 권한을 가지고 하나의 연결 블록 내의 관계를 조사하고 유지한 다음에 dp[i][j]는 전 i개의 연결 블록 안에 j개의 좋은 방안이 있다는 것을 나타낸다. 유일한 방안이기 때문에 출력 방안을 거꾸로 밀면 된다.
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define pb push_back
#define sd(n) scanf("%d",&n)
#define sdd(n,m) scanf("%d%d",&n,&m)
#define sddd(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define sld(n) scanf("%lld",&n)
#define sldd(n,m) scanf("%lld%lld",&n,&m)
#define slddd(n,m,k) scanf("%lld%lld%lld",&n,&m,&k)
#define sf(n) scanf("%lf",&n)
#define sff(n,m) scanf("%lf%lf",&n,&m)
#define sfff(n,m,k) scanf("%lf%lf%lf",&n,&m,&k)
#define ss(str) scanf("%s",str)
#define ansn() printf("%d
",ans)
#define lansn() printf("%lld
",ans)
#define r0(i,n) for(int i=0;i
#define r1(i,e) for(int i=1;i<=e;++i)
#define rn(i,e) for(int i=e;i>=1;--i)
#define mst(abc,bca) memset(abc,bca,sizeof abc)
#define lowbit(a) (a&(-a))
#define all(a) a.begin(),a.end()
#define pii pair
#define pll pair
#define mp(aa,bb) make_pair(aa,bb)
#define lrt rt<<1
#define rrt rt<<1|1
#define X first
#define Y second
#define PI (acos(-1.0))
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
//const ll mod = 1000000007 ;
const double eps=1e-9;
const int inf=0x3f3f3f3f;
//const ll infl = 100000000000000000;//1e17
const int maxn= 3e2+20;
const int maxm = 3e2+20;
//muv[i]=(p-(p/i))*muv[p%i]%p;
int in(int &ret) {
char c;
int sgn ;
if(c=getchar(),c==EOF)return -1;
while(c!='-'&&(c<'0'||c>'9'))c=getchar();
sgn = (c=='-')?-1:1;
ret = (c=='-')?0:(c-'0');
while(c=getchar(),c>='0'&&c<='9')ret = ret*10+(c-'0');
ret *=sgn;
return 1;
}
int fa[maxn<<1];
int d[maxn<<1];
int faf(int x)
{
if(fa[x]!=x)
{
int t = fa[x];
fa[x] = faf(t);
d[x] = d[x]^d[t];
}
return fa[x];
}
void un(int a,int b,int c)
{
int f1 = faf(a),f2 =faf(b);
if(f1!=f2)
{
fa[f2]=f1;
d[f2] = d[a]^d[b]^c;
}
}
vector<int>g[2][maxn<<1];
int num1[maxn<<1];
int num2[maxn<<1];
int dp[maxn<<1][maxn];
int rt[maxn<<1];
char s[100];
int main() {
#ifdef LOCAL
freopen("input.txt","r",stdin);
// freopen("output.txt","w",stdout);
#endif // LOCAL
int n,p1,p2;
while(~sddd(n,p1,p2),n||p1||p2)
{
r1(i,p1+p2)g[1][i].clear(),g[0][i].clear(),fa[i] = i,d[i] = 0,num1[i] = num2[i] = 0;
while(n--)
{
int a,b;
sdd(a,b);
ss(s);
if(s[0]=='n')un(a,b,1);
else un(a,b,0);
}
for(int i=1;i<=p1+p2;++i)
{
int x = faf(i);
if(d[i])++num1[x],g[1][x].pb(i);
else ++num2[x],g[0][x].pb(i);
}
mst(dp,0);
dp[0][0] = 1;
int c = 0;
for(int i=1;i<=p1+p2;++i)
{
if(faf(i)!=i)continue;
rt[++c] = i;
int mn = min(num1[i],num2[i]);
for(int j=p1;j>=mn;--j)
{
if(dp[c-1][j-num1[i]])
dp[c][j]+=dp[c-1][j-num1[i]];
if(dp[c-1][j-num2[i]])
dp[c][j]+= dp[c-1][j-num2[i]];
}
}
if(dp[c][p1]!=1)
{
puts("no");
continue;
}
vector<int>v;
while(c)
{
int r = rt[c];
if(dp[c-1][p1-num1[r]]==1)
{
int sz = g[1][r].size();
r0(i,sz)
{
v.pb(g[1][r][i]);
}
p1-=num1[r];
}
else
{
int sz = g[0][r].size();
r0(i,sz)v.pb(g[0][r][i]);
p1-=num2[r];
}
c--;
}
sort(all(v));
int sz = v.size();
r0(i,sz)
{
int ans = v[i];
ansn();
}
puts("end");
}
return 0;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
POJ 2236 Wireless Network 간편한 검색 및 수집The ACM (Asia Cooperated Medical team) have set up a wireless network with the lap computers, but an unexpected aftersho...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.