poj 1112 uva1627

来源:互联网 发布:本科毕业论文 知乎 编辑:程序博客网 时间:2024/06/06 11:04
状态是前i个能凑到的与j最相近的数。
/*test case152 3 5 01 4 5 3 01 2 5 01 2 3 04 3 2 1 0*/#include <cstdio>#include <cstring>#include <vector>#include <iostream>#include <cmath>#include <algorithm>#define INF 100000000using namespace std;const int maxn = 100 + 5, mid = 103;int head[maxn], V[maxn*maxn], skip[maxn*maxn], L, N;bool G[maxn][maxn],mark[maxn][2*maxn];int adjient[maxn], R, vis[maxn],d[maxn][2*maxn];struct Nima {  int id, type;  Nima(int id, int type) : id(id), type(type) {}};vector<Nima> liantong[maxn];// simple judgebool pd(int J) {    if(J<2*maxn && J >= 0) return true;    return false;}bool opt(int j, int u, int o) {  j -= mid;  if(abs(o-j) < abs(u-j)) return true;   return false;}void init() {  memset(d, 0, sizeof(d));  memset(G, 0, sizeof(G));  L = -1;  memset(head, -1, sizeof(head));  memset(vis, 0, sizeof(vis));  for(int i = 0; i <= R; i++) liantong[i].clear();  R = 0;}bool dfs(int dot, int& num) {  num+=vis[dot];  liantong[R].push_back(Nima(dot, vis[dot]));   for(int u = head[dot]; u != -1; u = skip[u])  {    if(!vis[V[u]]) {  vis[V[u]] = -vis[dot];  if(!dfs(V[u], num)) return false;}else if(vis[V[u]] == vis[dot]) return false;  }  return true;}int main() {int k;init();scanf("%d",&N);for(int i = 1; i <= N; i++) {  int x;  while(scanf("%d",&x)==1 && x) G[i][x] = 1;}for(int i = 1; i <= N; i++)  for(int j = i+1; j <= N; j++){  if(!G[i][j] || !G[j][i]) {V[++L] = j; skip[L] = head[i]; head[i] = L;V[++L] = i; skip[L] = head[j]; head[j] = L;  }}bool wrong = 0;for(int i = 1; i <= N; i++) {  if(!vis[i]) {    ++R;vis[i] = 1;k = 0;if(!dfs(i,k)){wrong = 1; break;}adjient[R] = k;  }}/*//test for(int i = 1; i <= R; i++) {  printf("liantong %d: ",i);  for(int j = 0; j < liantong[i].size(); j++) {    printf("%d ",liantong[i][j].id);  }  putchar('\n');}*/if(wrong) {printf("No solution\n");return 0; }//d[0][0~maxn*2-1] = 0;for(int i = 1; i <= R; i++) {  for(int j = 0; j < 2*maxn; j++) {    d[i][j] = INF;    if(pd(j-adjient[i]) && opt(j, d[i][j], d[i-1][j-adjient[i]]+adjient[i]) ) {      d[i][j] = d[i-1][j-adjient[i]] + adjient[i];// we choose to add      mark[i][j] = 1;}if(pd(j+adjient[i]) && opt(j, d[i][j], d[i-1][j+adjient[i]]-adjient[i]) ) {      d[i][j] = d[i-1][j+adjient[i]]-adjient[i]; // we choose to reduce      mark[i][j] = 0;}  }}vector<int> left, right;       // 1 for left, -1 for right; when mark is 0, we turn around ;for(int i = R, now = mid; i>=1; i--) {  if(mark[i][now]) {    for(int U = 0; U < liantong[i].size(); U++) {      Nima& K = liantong[i][U];      if(K.type == 1) left.push_back(K.id);      else right.push_back(K.id);}now -= adjient[i];  } else {    for(int U = 0; U < liantong[i].size(); U++) {      Nima& K = liantong[i][U];      if(K.type == -1) left.push_back(K.id);      else right.push_back(K.id);}now += adjient[i];  }}printf("%d",left.size()); sort(left.begin(), left.end());for(vector<int>:: iterator tat = left.begin(); tat != left.end(); ++tat) {  printf(" %d",*tat);                    }printf("\n");printf("%d",right.size()); sort(right.begin(), right.end());for(vector<int>:: iterator tat = right.begin(); tat != right.end(); ++tat) {      printf(" %d",*tat);}printf("\n");  return 0;}

1 0
原创粉丝点击