Online JudgeProblem SetAuthorsOnline ContestsUser
Web Board
Home Page
F.A.Qs
Statistical Charts
Problems
Submit Problem
Online Status
Prob.ID:
Register
Update your info
Authors ranklist
Current Contest
Past Contests
Scheduled Contests
Award Contest
User ID:
Password:
  Register

Re:这题详细用什么方法做?

Posted by sdlwwlp at 2011-07-20 18:29:45 on Problem 3270
In Reply To:Re:这题详细用什么方法做? Posted by:ccnujing at 2008-08-01 17:15:27
>  置换环...
/*
 * poj3270.cpp
 *
 *  Created on: 2011-7-20
 *      Author: will
 *      群论--置换环--黑书P248
 */
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using std::cout;
using std::endl;
int N,mi,ma,S;//S是循环个数
long long ans;
int a[10007],b[10007],K[10007],T[10007],ord[100007];//K是循环长度,T是每个循环最小数
int vis[10007];//vis[i]表示i在第几个循环当中
inline int min(int a,int b)
{
	return a<b?a:b;
}
inline int max(int a,int b)
{
	return a>b?a:b;
}
int main()
{
	int temp;
	memset(T,0x3f3f3f,sizeof(T));
	mi=999999999;
	scanf("%d",&N);
	for(int i=1;i<=N;i++)
	{
		scanf("%d",&temp);
		ord[temp]=i;
		ans+=temp;
		mi=min(temp,mi);
		ma=max(temp,ma);
	}
	int now=0;
	for(int i=0;i<=ma;i++)
		if(ord[i])
		{
			a[++now]=ord[i];
			b[now]=i;
		}
	for(int i=1;i<=N;i++)
	{
		if(!vis[i])
		{
			S++;
			K[S]++;
			T[S]=min(T[S],b[i]);
			vis[i]=true;
			now=a[i];
			while(!vis[now])
			{
				//printf("now=%d\n",now);
				K[S]++;
				T[S]=min(T[S],b[now]);
				vis[now]=true;
				now=a[now];
			}
		}
	}
	//printf("S=%d\n",S);

	for(int i=1;i<=S;i++)
			{
				ans+=min((K[i]-2)*T[i],T[i]+(K[i]+1)*mi);
			}
	cout<<ans<<endl;
	return 0;
}

Followed by:

Post your reply here:
User ID:
Password:
Title:

Content:

Home Page   Go Back  To top


All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator