标签:poj
| Time Limit: 1000MS | Memory Limit: 30000K | |
| Total Submissions: 4236 | Accepted: 1276 |
Description
Input
Output
Sample Input
5 2 1 3 4 5
Sample Output
3
Hint
题意是给你1到N这么多的点,要求有P次连接,将P次连接中给的点连接起来,举例比如说1到3要连接有两种连接方法,1-2-3或者1-5-4-3。求满足所有连接中最少需要多少个线段连接。
真没想到暴力竟然还能n*n这么暴。。。看了别人的想法之后,觉得精彩的地方第一点在于如果i 到i+1这个线段是断了的话,而要求连接的线段又恰好在这之间,(即只有一种方法将之连接,逆过去连接),这种时候的做法是将to[1]=start,to[end]=N+1,分成两段来想,还避免了那个断了的影响,觉得这种想法真是赞啊!!!
还有一点是to数组的使用比我之前想象的简单多了,to[i]表示从i开始到to[i]已经连接上了,如果等于0直接pass掉,这样一个一个枚举也很简单方便。
还有一点是duandian表示当前能够到达的最远的点,这里的使用也很赞。
这三点真的值得我去好好研磨。
代码:
#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <string>
#include <cstring>
using namespace std;
struct node
{
int start;
int end;
}node_one[10005];
bool cmp(node node1,node node2)
{
if(node1.start == node2.start)
return node1.end< node2.end;
return node1.start<node2.start;
}
#define INF 0x3f3f3f3f
int N,P,i,j,Q1,Q2,Qmin,Qmax,ans,h;
int to[1005];
int main()
{
cin>>N>>P;
for(i=1;i<=P;i++)
{
cin>>Q1>>Q2;
node_one[i].start = min(Q1,Q2);
node_one[i].end = max(Q1,Q2);
}
sort(node_one+1,node_one+P+1,cmp);
ans=INF;
for(i=1;i<=N;i++)
{
memset(to,0,sizeof(to));
for(j=1;j<=P;j++)
{
if(node_one[j].end>=i+1 && node_one[j].start<=i)
{
to[1]=max(to[1],node_one[j].start);
to[node_one[j].end]=N+1;
}
else
{
to[node_one[j].start]=max(to[node_one[j].start],node_one[j].end);
}
}
int duandian=0,result=0;
for(j=1;j<=N;j++)
{
if(to[j]==0)continue;
if(to[j]>duandian)
{
if(j>=duandian)
{
result+=(to[j]-j);
}
else
{
result+=(to[j]-duandian);
}
duandian=to[j];
}
}
ans=min(ans,result);
}
cout<<ans<<endl;
return 0;
}版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:poj
原文地址:http://blog.csdn.net/u010885899/article/details/46981157