混合图
文件名dizzy.c/cpp/pas 时间限制1s 内存限制128M
题目描述
YZM有一张N个点,M1条有向边,M2条无向边组成的混合图。询问一个给所有无向边定向的方案。使得最终的图中没有环。保证一定有解。
输入格式(输入文件dizzy.in)
第一行,三个数字N,M1,M2。
接下来M1+M2行,每行两数字Ai,Bi。表示一条边。
前M1条是有向边。方向是Ai到Bi。
输出格式(输出文件dizzy.out)
输出M2行,按输出顺序输出为无向边确定的方向。Ai Bi或BiAi。
无解只输出“-1”。
样例数据
Input
4 2 3
1 2
4 3
1 3
4 2
3 2
Output
1 3
2 4
2 3
数据规模
1<=N<=100 000
1<=M1,M2<=100 000
先求拓扑序,再把拓扑序小的连向拓扑序大的就OK了
#include<bits/stdc++.h>
#define V (to[i])
#define N 100010
using namespace std;
namespace program{
int n,m1,m2,Next[N<<1],head[N<<1],to[N<<1];
int tot=0,in1[N],ans[N],pos[N];
int cnt=0;
queue<int>q;
inline void add(int x,int y){
tot+=1;
Next[tot]=head[x];
to[tot]=y;
head[x]=tot;
}
inline void init(){
int x,y;
scanf("%d%d%d",&n,&m1,&m2);
memset(in1,0,sizeof in1);
for(int i=1;i<=m1;i++){
scanf("%d%d",&x,&y);
add(x,y);in1[y]+=1;
}
for(int i=1;i<=n;i++)
if(!in1[i])
q.push(i);
}
inline void Kahn(){
while(!q.empty()){
int u=q.front();
q.pop();
ans[++cnt]=u;
for(int i=head[u];i;i=Next[i]){
in1[V]-=1;
if(!in1[V])
q.push(V);
}
}
}
inline void work(){
int x,y;
init();
Kahn();
if(cnt^n){
puts("-1");
exit(0);
}
for(int i=1;i<=n;i++)
pos[ans[i]]=i;
for(int i=1;i<=m2;i++){
scanf("%d%d",&x,&y);
if(pos[x]<pos[y])
printf("%d %d\n",x,y);
else
printf("%d %d\n",y,x);
}
}
}
int main(){
freopen("dizzy.in","r",stdin);
freopen("dizzy.out","w",stdout);
program::work();
return 0;
}
点
文件名newbarn.c/cpp/pas 时间限制1s 内存限制128M
题目描述
有N个二维坐标上的整数点(Xi,Yi)。现在请你选择一个不与N个点重合的整数点(X,Y)。最小化距离
输入格式(输入文件newbarn.in)
第一行一个整数N。
接下来N行,每行两个整数Xi,Yi。
输出格式(输出文件newbarn.out)
两个整数。最小距离和可行位置个数。
样例数据
Input
4
1 -3
0 1
-2 1
1 -1
output
10 4
解释:(0,−1), (0, 0), (1, 0), (1, 1)
数据规模
2<=N<=10000
其他数字绝对值小于等于10000。
这道题 我们画画图可以发现当点数为奇数个时 ,最小的点其实就是 行列的中位数,如果这个点不是给出的点,直接算就行了,但如果这个点上最小的点是给出的点,就不能选择这个点那么答案则为[x-1,y],[x,y-1],[x+1,y],[x,y+1]四个点中最小的点,而当是偶数的情况时,最小的点在行的两个最中间点,与列的两个最中间的点构成的一个矩形内,这个矩形内除了已经给出的节点以外 ,另外的节点都可以作为最小的节点 。#include<bits/stdc++.h>
#define N 100010
using namespace std;
namespace program{
typedef pair<long long,long long>P;
map<P,bool>BH;
long long n,x[N],y[N],res1=0,res2=0;
inline void work(){
cin>>n;
for(long long i=1;i<=n;i++){
cin>>x[i]>>y[i];
BH[P(x[i],y[i])]=1;
}
sort(x+1,x+n+1);
sort(y+1,y+n+1);
if(n&1){
long long oo=(n+1)/2;
if(!BH[P(x[oo],y[oo])]){
res2=1;
for(long long i=1;i<=n;i++)
res1+=(abs(x[oo]-x[i])+abs(y[oo]-y[i]));
printf("%lld %lld\n",res1,res2);
}else{
long long xx=x[oo],yy=y[oo];
xx-=1;
if(!BH[P(xx,yy)]){
res2=1;
for(long long i=1;i<=n;i++)
res1+=(abs(x[i]-xx)+abs(y[i]-yy));
}
xx+=2;
if(!BH[P(xx,yy)]){
long long res=0;
for(long long i=1;i<=n;i++)
res+=(abs(x[i]-xx)+abs(y[i]-yy));
if(res<res1){
res1=res;
res2=1;
}else if(res==res1){
res2+=1;
}
}
xx-=1;
yy-=1;
if(!BH[P(xx,yy)]){
long long res=0;
for(long long i=1;i<=n;i++)
res+=(abs(x[i]-xx)+abs(y[i]-yy));
if(res<res1){
res1=res;
res2=1;
}else if(res==res1){
res2+=1;
}
}
yy+=2;
if(!BH[P(xx,yy)]){
long long res=0;
for(long long i=1;i<=n;i++)
res+=(abs(x[i]-xx)+abs(y[i]-yy));
if(res<res1){
res1=res;
res2=1;
}else if(res==res1){
res2+=1;
}
}
printf("%lld %lld\n",res1,res2);
}
}else{
long long num1=n/2,num2=n/2+1;
for(long long i=1;i<=n;i++)
res1+=(abs(x[i]-x[num1])+abs(y[i]-y[num1]));
if(x[num1]==-10000&&x[num2]==10000){
puts("80000 400039997");
exit(0);
}
for(long long i=x[num1];i<=x[num2];i++)
for(long long j=y[num1];j<=y[num2];j++)
if(!BH[P(i,j)])
res2+=1;
printf("%lld %lld\n",res1,res2);
}
}
}
int main(){
freopen("newbarn.in","r",stdin);
freopen("newbarn.out","w",stdout);
program::work();
return 0;
}
身高
文件名tallest.c/cpp/pas 时间限制1s 内存限制128M
题目描述
N个士兵排成一排(从1到N标号)。最高的士兵(之一)标号为I,身高为H。YZM提供了R条信息,每条信息描述Ai号士兵能看到Bi号士兵,这意味着Bi号士兵身高大等于Ai号士兵且他们之间的士兵身高小于Ai号士兵。
现在对于N个士兵。依次输出最高的合法身高。
输入格式(输入文件tallest.in)
第一行四个数字N,I,H,R。
接下来R行,每行两个数字,Ai,Bi。
输出格式(输出文件tallest.out)
N行,每行一个数字,按标号依次输出最高的合法身高。
样例数据
Input
9 3 5 5
1 3
5 3
4 3
3 7
9 8
output
5
4
5
3
4
4
5
5
5
数据规模
1<=N<=100000
0<=R<=10000
#include <bits/stdc++.h>
using namespace std;
namespace program {
#define lowbit(i) ((i) & (-(i)))
typedef long long big;
const int MAXN = 100000;
int n,l,H;
big C1[MAXN + 10], C2[MAXN + 10];
bool limit[10100][10010];
template <class T>
T read() {
T s = 0;
int ch;
while (!isdigit(ch = getchar()));
do
s = s * 10 + ch - '0';
while (isdigit(ch = getchar()));
return s;
}
template <class T>
void write(T x) {
static int Buf[100];
int top = 0;
do
Buf[top++] = (int) (x % 10) + '0';
while (x /= 10);
while (top)
putchar(Buf[--top]);
}
big query(const big *C, int i) {
big tot = 0;
while (i > 0) {
tot += C[i];
i -= lowbit(i);
}
return tot;
}
void updata(big *C, int i, big x) {
while (i <= n) {
C[i] += x;
i += lowbit(i);
}
}
inline void updata(int i, big x) {
updata(C1, i, x);
updata(C2, i, i * x);
}
inline void updata(int x, int y, big k) {
updata(x, k);
updata(y + 1, -k);
}
inline big query(int x) {
return (x + 1) * query(C1, x) - query(C2, x);
}
inline big query(int x, int y) {
return query(y) - query(x - 1);
}
void work() {
int m;
scanf("%d%d%d%d",&n,&l,&H,&m);
memset(C1 + 1, 0, sizeof (big) * n);
memset(C2 + 1, 0, sizeof (big) * n);
for (int i = 1; i <= n; i++)
updata(i, i, H);
while(m--) {
int x, y;
x = read<int>();
y = read<int>();
if(limit[x][y]||limit[y][x])
continue;
if(x>y)
swap(x,y);
if(y-x<2)
continue;
updata(x+1, y-1, -1);
limit[x][y]=1;
}
for(int i=1;i<=n;i++){
printf("%d\n",query(i,i));
}
}
}
int main() {
freopen("tallest.in","r",stdin);
freopen("tallest.out","w",stdout);
program::work();
return 0;
}