static int open_exec_filter(struct cgit_filter *base, va_list ap) { struct cgit_exec_filter *filter = (struct cgit_exec_filter *)base; int i; for (i = 0; i < filter->base.argument_count; i++) filter->argv[i + 1] = va_arg(ap, char *); filter->old_stdout = chk_positive(dup(STDOUT_FILENO), "Unable to duplicate STDOUT"); chk_zero(pipe(filter->pipe_fh), "Unable to create pipe to subprocess"); filter->pid = chk_non_negative(fork(), "Unable to create subprocess"); if (filter->pid == 0) { close(filter->pipe_fh[1]); chk_non_negative(dup2(filter->pipe_fh[0], STDIN_FILENO), "Unable to use pipe as STDIN"); execvp(filter->cmd, filter->argv); die_errno("Unable to exec subprocess %s", filter->cmd); } close(filter->pipe_fh[0]); chk_non_negative(dup2(filter->pipe_fh[1], STDOUT_FILENO), "Unable to use pipe as STDOUT"); close(filter->pipe_fh[1]); return 0; }
int cgit_open_filter(struct cgit_filter *filter) { filter->old_stdout = chk_positive(dup(STDOUT_FILENO), "Unable to duplicate STDOUT"); chk_zero(pipe(filter->pipe_fh), "Unable to create pipe to subprocess"); filter->pid = chk_non_negative(fork(), "Unable to create subprocess"); if (filter->pid == 0) { close(filter->pipe_fh[1]); chk_non_negative(dup2(filter->pipe_fh[0], STDIN_FILENO), "Unable to use pipe as STDIN"); execvp(filter->cmd, filter->argv); die("Unable to exec subprocess %s: %s (%d)", filter->cmd, strerror(errno), errno); } close(filter->pipe_fh[0]); chk_non_negative(dup2(filter->pipe_fh[1], STDOUT_FILENO), "Unable to use pipe as STDOUT"); close(filter->pipe_fh[1]); return 0; }
void dfs(int x,int y,int c){ // 如果找到了最理想结果,则不必继续搜索 if(flag) return ; pii temp[N]; // expt表示比赛(x,y)预计要安排到的轮次数 int expt = c / tmpn; // sum表示当前的方差和 int sum = 0; for(int i = 1; i <= cntn; i++) sum += differ(hash[i]); if(sum > TMP+EPS) return; // 此处是一个剪枝,如果继续搜索没有当前结果好,则舍弃 if(y == ANS[x].size()) x ++, y = 0; if(x == len) { // 搜索到终点 if(sum == TMP) { flag = 1; } // 如果当前结果比最优结果好,那么记录当前结果 if(sum < best ) { // 按照之前的要求,某行的轮空不超过1 for(int i = 1; i <= base; i++) if(chk_zero(hash[i]) > 1) return ; best = sum; memcpy(last_ans,ans,sizeof(ans)); memcpy(myconf,conf,sizeof(conf)); } return; } //p是当前比赛 pii p = ANS[x][y]; int a =p.first, b = p.second; for(int i = 0; i < coln; i++) temp[i] = make_pair(use[i],i); // 数组use是赛道的使用频率 sort(temp,temp+coln); // 先从使用频率最小的赛道开始检查 for(int q = 0; q < coln; q++){ int j = temp[q].second; hash[a][j]++; hash[b][j]++; use[j] ++; // 假设选择赛道j,更新hash && use 数组 // dif是能容忍的hash值最大的最大最小值的差 int dif = coln <= 4 ? 3 : 2; if(differ(hash[a]) <= dif && differ(hash[b]) <= dif) { int i = expt,cost = 0; if(ans[i][j] == zero && !_vis[a][i] && !_vis[b][i]) // tight_col是代表列数 <=2 if(tight_col || i == 0 || !conflict(ans[i-1][j],a,b)){ _vis[a][i] = 1; _vis[b][i] = 1; ans[i][j] = p; dfs(x,y+1,c+1); if(flag) return ; _vis[a][i] = 0; _vis[b][i] = 0; ans[i][j] = zero; } } // 搜索结束,回溯 use[j]--; hash[a][j]--; hash[b][j]--; } }