테마 모음 (지속 업데이트)
55948 단어 acm
무엇이 병 찰 집 입 니까?그리고 집합 은 트 리 형 데이터 구조 로 서로 교차 하지 않 는 집합 과 조회 문 제 를 처리 하 는 데 사용 된다.일반적인 조작
void init()
{
for(int i=1;i<=n;i++)
father[i]=i;
}
int getfather(int x)
{
if(father[x]==x)return x;
else return father[x]=getfather(father[x]);
}
여기 서 경 로 를 압축 하 는 방법 으로 i 가 속 한 집합 을 루트 노드 로 바 꾸 면 다음 에 다시 검색 할 때 O (1) 의 시간 안에 결 과 를 얻 을 수 있 습 니 다.
void merge(int a,int b)
{
int f1=getfather(a);
int f2=getfather(b);
if(f1!=f2)
{
father[f1]=f2;// father[f2]=f1;
;
}
}
int getfather(int x)
{
if(father[x]==x)return x;
else
{
int t=father[x];//
father[x]=getfather(father[x]);
dis[x]+=dis[t];// x
return father[x];
}
}
이곳 의 dis 배열 은 각 점 에서 조상 까지 의 거 리 를 나타 낸다.
1. 최소 생 성 트 리
선로 계획 시간 제한: 1 Sec 메모리 제한: 128 MB 제목 은 n 개 마을 간 에 통신 선 로 를 가설 하여 임의의 두 마을 간 에 모두 통신 할 수 있 도록 설명 한다.두 마을 a, b 간 통신 이 가능 하 며, 그들 사이 에 하나의 통신 라인 이 존재 하거나 마을 c 가 존재 하면 a, c 와 b, c 간 에 모두 통신 이 가능 합 니 다.마을 간 에 통신 선 을 가설 하 는 대 가 를 주 고 최소 의 총 대 가 를 구하 다.첫 줄 에 두 개의 정수 n, m 를 포함 하고 마을 수량 과 통신 선 로 를 가설 할 수 있 는 마을 대 수 를 입력 하 십시오.아래 m 줄, 각 줄 의 세 개의 정수 a, b, c 는 마을 a, b 사이 에 선 로 를 가설 하 는 대 가 는 c (마을 은 0 부터 번호) 임 을 나타 낸다.하나의 정수, 최소 총 대 가 를 출력 하 다.샘플 입력 복사
3 3
0 1 1
1 2 1
2 0 3
샘플 출력 복사
2
50% 의 데이터 에 대해 n < = 100, m < = n ^ 2 는 모든 데이터 에 대해 1 < = n < = 10 ^ 5;n - 1 < = m < = 10 ^ 5, 모든 대 가 는 [0, 10 ^ 6] 범위 내 에서 문제 가 해 결 될 것 을 보증 합 니 다.
최소 생 성 트 리 kruskal 알고리즘 + 템 플 릿 문 제 를 찾 습 니 다. WA 의 점 은 출발점 좌표 가 종점 좌표 보다 작 음 을 보장 하 는 것 도 아니 고 선택
father[f1]=f2
또는 father[f2]=f1
도 아 닙 니 다. 마을 대 수 를 읽 을 때 1 부터 m 까지 입 니까? 0 에서 m - 1 까지 입 니까? 마지막 총 대 가 는 long long 형 일 수 있 습 니 다.처음에 나 는 모든 총 대 가 를 [0, 10 ^ 6] 범위 내 에서 91% 의 데 이 터 를 통과 할 수 밖 에 없다 고 잘못 보 았 다.#include
#include
using namespace std;
typedef struct village
{
int Start,End,Weight;
}v;
int father[100005];
v vil[100005];
int getfather(int x)
{
if(father[x]==x)return x;
else return father[x]=getfather(father[x]);
}
int cmp(const void*a,const void*b)
{
v*x=(v*)a;
v*y=(v*)b;
return x->Weight-y->Weight;
}
int main()
{
int n,m,edge=0,a,b,c;
long long int cost=0;
scanf("%d %d",&n,&m);
for(int i=0;i<=n-1;i++)father[i]=i;
for(int i=0;i<=m-1;i++)
{
scanf("%d %d %d",&a,&b,&c);
vil[i].Start=a;
vil[i].End=b;
vil[i].Weight=c;
}
int f1,f2;
qsort(vil,m,sizeof(vil[0]),cmp);
for(int i=0;i<=m-1;i++)
{
f1=getfather(vil[i].Start);
f2=getfather(vil[i].End);
if(f1!=f2)
{
father[f1]=f2;
edge++;
cost+=vil[i].Weight;
if(edge==n-1)break;
}
}
printf("%lld",cost);
return 0;
}
/**************************************************************
Language: C++
Result:
Time:65 ms
Memory:3852 kb
****************************************************************/
2. 최대 생 성 트 리
sunflower 시간 제한: 1 Sec 메모리 제한: 128 MB 제목 은 작은 N 이 작은 T 집의 화원 에 자주 산책 하 는 것 을 묘사 합 니 다. 작은 T 집의 화원 은 N 개의 긴 정자 와 M 개의 도로 가 정 자 를 연결 하고 있 지만 작은 T 의 화원 은 너무 복잡 합 니 다. 작은 N 은 길 치 로 자주 들 어간 후에 찾 을 수 없 는 길 로 계속 링 안 을 돌 고 있 습 니 다.그래서 작은 N 은 작은 T 에 게 그 중의 일부 길 을 해 바라 기 를 심 어 나머지 길 에 고리 가 생기 지 않도록 해 야 한다.해 바라 기 는 심기 가 불편 하기 때문에 i 번 도로 길이 인 Li 는 Li 개의 해 바라 기 를 심 어야 한다. 그래서 T 는 그 가 최소한 몇 개의 해 바라 기 를 심 어야 작은 N 의 요 구 를 만족 시 킬 수 있 는 지 알 고 싶다.첫 번 째 줄 의 정수 N, M 을 입력 하면 화원 의 정자 수 와 도로 수 를 나타 낸다.다음 M 줄 은 줄 당 3 개의 정수 A, B, C 로 A 와 B 를 연결 하 는 길이 가 C 인 도로 가 있다 는 것 을 나타 낸다.작은 T 가 최소한 심 어야 할 해바라기 수 를 나타 내 는 한 줄 의 정 수 를 출력 합 니 다.샘플 입력 복사
5 5
1 2 5
1 4 4
3 4 3
2 3 2
3 5 1
샘플 출력 복사
2
제시 100% 의 데이터 에 대하 여 1 ≤ N ≤ 10 ^ 5, 1 ≤ M ≤ 2×10 ^ 5, 0 류 는 '파 권 법' 의 원리 에 비해 문 제 는 연관 성 을 바 꾸 지 않 는 전제 에서 매번 가중치 가 가장 작은 변 을 삭제 하고 삭제 할 수 없 을 때 까지 최대 로 트 리 문 제 를 생 성 하 는 것 과 같다.kruskal 알고리즘 의 정렬 방식 을 가중치 에서 작은 순서 로 바 꾸 기만 하면 됩 니 다.
#include
#include
using namespace std;
typedef struct Edge
{
int Start,End,cost;
}edge;
int cmp(const void*a,const void*b)
{
edge*x=(edge*)a;
edge*y=(edge*)b;
return y->cost-x->cost;
}
edge road[200005];
int father[100005];
int n,m,a,b,c,cnt=0;
int getfather(int v)
{
if(father[v]==v)return v;
else return father[v]=getfather(father[v]);
}
int main()
{
long long int sum=0;
scanf("%d %d",&n,&m);
for(int i=1;i<=m;i++)
{
scanf("%d %d %d",&a,&b,&c);
road[i].Start=a;
road[i].End=b;
road[i].cost=c;
sum+=road[i].cost;
}
qsort(road+1,m,sizeof(road[1]),cmp);//
for(int i=1;i<=n;i++)father[i]=i;
long long int sum1=0;
int fat1,fat2;
for(int i=1;i<=m;i++)
{
fat1=getfather(road[i].Start);
fat2=getfather(road[i].End);
if(fat1!=fat2)
{
sum1+=road[i].cost;
father[fat2]=fat1;
cnt++;
if(cnt==n-1)break;
}
}
printf("%lld",sum-sum1);
return 0;
}
/**************************************************************
Language: C++
Result:
Time:128 ms
Memory:6196 kb
****************************************************************/
3. 연통 도 문제
tunnel 시간 제한: 1 Sec 메모리 제한: 128 MB 제목 은 한 마을 이 자신의 지하철 노선 망 을 구축 하 는 데 착수 하고 있다 는 것 을 설명 한다.마을 은 많은 작은 섬 에 자리 잡 고 있 으 며 작은 섬 사 이 는 터널 이나 다 리 를 통 해 연결된다.지하철 은 기 존의 교량 과 터널 을 바탕 으로 건설 되 었 다.지하철 은 주로 지하 에 있 기 때문에 다 리 를 적 게 쓸 수록 좋다.마을 주민 들 은 지하철 로 만 두 개의 작은 섬 사 이 를 오 가 며 여행 할 수 있 기 를 바란다.다행히도 우 리 는 이 요 구 를 충족 시 킬 터널 과 다리 가 충분 하기 때문에 새로운 터널 이나 다 리 를 건설 할 필요 가 없다.당신 의 임 무 는 이런 지하철 노선 망 을 구축 하려 면 적어도 몇 개의 다 리 를 사용 해 야 한 다 는 것 을 계산 하 는 것 입 니 다.입력 입력 은 K + M + 1 줄 을 포함 합 니 다.첫 줄 은 N, M, K 세 개 를 포함 하 는데 그 중에서 N 은 작은 섬 수량 이 고 M 은 터널 수량 이 며 K 는 교량 수량 이다.아래 M 줄 은 각 줄 에 두 개의 숫자 가 있 는데 해당 하 는 터널 이 연 결 된 작은 섬의 번 호 를 나타 내 고 번 호 는 1 에서 N 까지 이다.K 행 을 내 려 가면 줄 마다 똑 같은 방식 으로 다 리 를 묘사 합 니 다.최소 필요 한 교량 수 를 출력 하 다.샘플 입력 복사
6 3 4
1 2
2 3
4 5
1 3
3 4
4 6
5 6
샘플 출력 복사
2
제시 100% 의 데이터 에 대하 여 1 ≤ N ≤ 10000, 1 ≤ K ≤ 12000, 1 ≤ M ≤ 12000 은 흑체 부분 에서 알 고 있 으 며, 최종 적 으로 얻 은 그림 은 반드시 연통 도 이 므 로 터널 을 진행 하고 수집 하여 약간의 연통 분기 만 얻 고, 연통 분기 수 (각 점 의 조상 노드 는 현재 노드) - 1 을 통계 하면 답 을 얻 을 수 있다.
#include
typedef struct node
{
int Start,End;
}edge;
edge tunnel[12005];
edge bridge[12005];
int father[10005];
int k,n,m;
int getfather(int x)
{
if(father[x]==x)return x;
else return father[x]=getfather(father[x]);
}
int main()
{
scanf("%d %d %d",&n,&m,&k);
int cnt=0;
for(int i=1;i<=m;i++)
{
scanf("%d %d",&tunnel[i].Start,&tunnel[i].End);
}
for(int i=1;i<=k;i++)
{
scanf("%d %d",&bridge[i].Start,&bridge[i].End);
}
for(int i=1;i<=n;i++)father[i]=i;
int f1,f2;
for(int i=1;i<=m;i++)
{
f1=getfather(tunnel[i].Start);
f2=getfather(tunnel[i].End);
if(f1!=f2)father[f2]=f1;
}
for(int i=1;i<=n;i++)
if(father[i]==i)cnt++;
printf("%d",cnt-1);
return 0;
}
/**************************************************************
Language: C++
Result:
Time:11 ms
Memory:1344 kb
****************************************************************/
4. 고리 유 무 판단
무선 방송 시간 제한: 2 Sec 메모리 제한: 256 MB 의 한 방송 사 는 한 지역 에 무선 방송 발사 장 치 를 설치 해 야 한다.이 지역 에는 n 개의 작은 마을 이 있 는데 마을 마다 송신기 한 대 를 설치 하고 각자 의 프로그램 을 방송 해 야 한다.그러나 이 회 사 는 FM 104.2 와 FM 98.6 두 밴드 의 권한 만 수 여 받 았 고 같은 밴드 의 발사 기 회 를 이용 해 서로 방해 했다.각 송신기 의 신호 커버 범 위 는 원심, 20km 를 반경 으로 하 는 원형 구역 으로 알려 져 있 기 때문에 20km 이하 의 두 마을 에서 같은 파 도 를 사용 하면 파 단 간섭 으로 프로그램 을 제대로 듣 지 못 한다.현재 20km 이하 의 작은 마을 목록 을 제시 해 이 회사 가 전 지역 주민 들 이 방송 프로그램 을 정상적으로 들 을 수 있 는 지 판단 해 보 자.첫 번 째 행위 의 정수 n, m 를 입력 하 십시오. 각각 작은 마을 의 개수 와 그 다음 20km 이하 의 작은 마을 의 수 입 니 다.다음 m 행 은 줄 당 2 개의 정 수 를 나타 내 며 두 마을 의 거 리 는 20km 이하 (번 호 는 1 부터) 임 을 나타 낸다.출력 이 요 구 를 만족 시 킬 수 있다 면 출력 1, 그렇지 않 으 면 출력 - 1.샘플 입력 복사
4 3
1 2
1 3
2 4
샘플 출력 복사
1
제한 1 ≤ n ≤ 10000 1 ≤ m ≤ 30000 은 주어진 20km 마을 목록 의 공간 특성 을 고려 할 필요 가 없다. 예 를 들 어 삼각형 부등식 을 만족 시 키 는 지, 전달 성 을 이용 하여 더 많은 정 보 를 내 놓 을 수 있 는 지 등 이다.
20km 미 만 을 연결 관계 로 보고 주어진 모든 점 을 얻어 그림 을 만 들 수 있다. 그림 에 고리 가 존재 하지 않 거나 길이 가 짝수 인 고리 가 존재 할 때 요 구 를 만족 시 킬 수 있 고 나머지 상황 에서 요 구 를 만족 시 키 지 못 하기 때문에 문 제 는 고리 와 고리 의 길이 문 제 를 찾 는 것 으로 바 뀌 었 다.회로 에 고리 가 존재 하 는 지 판단 하고 수집 할 수 있 으 며 두 점 (출발점, 종점) 의 조상 결점 이 동시에 하나의 고 리 를 구성 할 수 있다.dis 배열 을 이용 하여 결점 에서 조상 까지 의 거 리 를 기록 하고 한 변 의 두 점 에 대해 규칙 을 찾 아 보면 두 점 에서 조상 까지 의 거리 차이 가 짝수 일 때 현재 의 변 을 더 하면 링 의 길 이 를 홀수 로 얻 을 수 있다.반대로 두 점 에서 조상 까지 의 거리의 차 이 는 홀수 일 때 현재 의 변 을 더 하면 마침 고리 의 길 이 는 짝수 이다.
#include
using namespace std;
int father[10005];
typedef struct Node
{
int Start,End;
}node;
node town[30005];
int dis[10005]={0};//
bool cir=false;//
bool flag=false;//
//
int getfather(int x)//
{
if(father[x]==x)return x;
else
{
int t=father[x];
father[x]=getfather(father[x]);
dis[x]+=dis[t];//
return father[x];
}
}
int main()
{
int n,m,a,b;
scanf("%d %d",&n,&m);
for(int i=1;i<=n;i++)father[i]=i;// ,
for(int i=1;i<=m;i++)
{
scanf("%d %d",&a,&b);
if(a>b)
{
int t=a;
a=b;
b=t;
}
town[i].Start=a;
town[i].End=b;
}
int f1,f2;
for(int i=1;i<=m;i++)
{
f1=getfather(town[i].Start);
f2=getfather(town[i].End);
if(f1==f2)// ,
{
cir=true;
if((dis[town[i].Start]-dis[town[i].End])%2==0)flag=true;//
}
else//
{
father[f1]=f2;//
dis[f1]=dis[town[i].End]+1-dis[town[i].Start];//
}
}
if(cir==false)printf("1");//
else if(flag==false)printf("1");//
else printf("-1");//
return 0;
}
/**************************************************************
Language: C++
Result:
Time:4 ms
Memory:4816 kb
****************************************************************/
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
AWS에서 사용하는 SSL 인증서 관리를 IAM에서 ACM으로 변경해야 하는 이유자신이 담당하는 시스템에서 ELB에 등록한 SSL 인증서를 IAM 관리에서 ACM 관리로 변경했습니다. AWS 기능을 사용하여 SSL 인증서를 관리하는 방법에는 두 가지가 있습니다. IAM을 이용하는 방법과 ACM을...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.